From d012560ea1278ac3f203b5f7623c72be80f43060 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 10 Dec 2021 23:06:19 +0100 Subject: [PATCH 001/631] Introduce range_raw over Prefix --- packages/storage-plus/src/indexes/multi.rs | 18 ++++--- packages/storage-plus/src/indexes/unique.rs | 60 ++++++++++++++------- packages/storage-plus/src/prefix.rs | 43 +++++++++++---- 3 files changed, 87 insertions(+), 34 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 4b8bd5c8e..1ee2373d2 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -144,29 +144,32 @@ where IK: PrimaryKey<'a> + Prefixer<'a>, { pub fn prefix(&self, p: IK) -> Prefix, T> { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), self.pk_namespace, deserialize_multi_v, + deserialize_multi_v, ) } pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix, T> { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), self.pk_namespace, deserialize_multi_v, + deserialize_multi_v, ) } fn no_prefix(&self) -> Prefix, T> { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &[], self.pk_namespace, deserialize_multi_v, + deserialize_multi_v, ) } @@ -257,20 +260,22 @@ where IK: PrimaryKey<'a> + Prefixer<'a>, { pub fn prefix_de(&self, p: IK) -> Prefix { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), self.pk_namespace, deserialize_multi_kv::, + deserialize_multi_v, ) } pub fn sub_prefix_de(&self, p: IK::Prefix) -> Prefix { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), self.pk_namespace, deserialize_multi_kv::, + deserialize_multi_v, ) } } @@ -336,11 +341,12 @@ where } fn no_prefix_de(&self) -> Prefix { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( self.idx_namespace, &[], self.pk_namespace, deserialize_multi_kv::, + deserialize_multi_v, ) } } diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 13d033475..922f3f647 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -113,21 +113,33 @@ where } pub fn prefix(&self, p: IK::Prefix) -> Prefix, T> { - Prefix::with_deserialization_function(self.idx_namespace, &p.prefix(), &[], |_, _, kv| { - deserialize_unique_v(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &p.prefix(), + &[], + |_, _, kv| deserialize_unique_v(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix, T> { - Prefix::with_deserialization_function(self.idx_namespace, &p.prefix(), &[], |_, _, kv| { - deserialize_unique_v(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &p.prefix(), + &[], + |_, _, kv| deserialize_unique_v(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } fn no_prefix(&self) -> Prefix, T> { - Prefix::with_deserialization_function(self.idx_namespace, &[], &[], |_, _, kv| { - deserialize_unique_v(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &[], + &[], + |_, _, kv| deserialize_unique_v(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } /// returns all items that match this secondary index, always by pk Ascending @@ -233,20 +245,32 @@ where } pub fn prefix_de(&self, p: IK::Prefix) -> Prefix { - Prefix::with_deserialization_function(self.idx_namespace, &p.prefix(), &[], |_, _, kv| { - deserialize_unique_kv::(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &p.prefix(), + &[], + |_, _, kv| deserialize_unique_kv::(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } pub fn sub_prefix_de(&self, p: IK::SubPrefix) -> Prefix { - Prefix::with_deserialization_function(self.idx_namespace, &p.prefix(), &[], |_, _, kv| { - deserialize_unique_kv::(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &p.prefix(), + &[], + |_, _, kv| deserialize_unique_kv::(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } fn no_prefix_de(&self) -> Prefix { - Prefix::with_deserialization_function(self.idx_namespace, &[], &[], |_, _, kv| { - deserialize_unique_kv::(kv) - }) + Prefix::with_deserialization_functions( + self.idx_namespace, + &[], + &[], + |_, _, kv| deserialize_unique_kv::(kv), + |_, _, kv| deserialize_unique_v(kv), + ) } } diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 808d62638..4356830c2 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -67,10 +67,11 @@ impl<'a, K: Prefixer<'a>> PrefixBound<'a, K> { } } +type DeserializeVFn = fn(&dyn Storage, &[u8], Record) -> StdResult>; + type DeserializeKvFn = fn(&dyn Storage, &[u8], Record) -> StdResult<(::Output, T)>; -#[allow(dead_code)] pub fn default_deserializer_v( _: &dyn Storage, _: &[u8], @@ -98,7 +99,8 @@ where // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed data: PhantomData, pk_name: Vec, - de_fn: DeserializeKvFn, + de_fn_kv: DeserializeKvFn, + de_fn_v: DeserializeVFn, } impl Deref for Prefix @@ -119,29 +121,49 @@ where T: Serialize + DeserializeOwned, { pub fn new(top_name: &[u8], sub_names: &[Key]) -> Self { - Prefix::with_deserialization_function( + Prefix::with_deserialization_functions( top_name, sub_names, &[], default_deserializer_kv::, + default_deserializer_v, ) } - pub fn with_deserialization_function( + pub fn with_deserialization_functions( top_name: &[u8], sub_names: &[Key], pk_name: &[u8], - de_fn: DeserializeKvFn, + de_fn_kv: DeserializeKvFn, + de_fn_v: DeserializeVFn, ) -> Self { let storage_prefix = nested_namespaces_with_key(&[top_name], sub_names, b""); Prefix { storage_prefix, data: PhantomData, pk_name: pk_name.to_vec(), - de_fn, + de_fn_kv, + de_fn_v, } } + pub fn range_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, max, order) + .map(move |kv| (de_fn)(store, &*pk_name, kv)); + Box::new(mapped) + } + pub fn range<'a>( &self, store: &'a dyn Storage, @@ -153,7 +175,7 @@ where T: 'a, K::Output: 'a, { - let de_fn = self.de_fn; + 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)); @@ -183,7 +205,7 @@ where T: 'a, K::Output: 'static, { - let de_fn = self.de_fn; + 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)); @@ -201,7 +223,7 @@ where T: 'a, K::Output: 'static, { - let de_fn = self.de_fn; + 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))) @@ -326,7 +348,8 @@ mod test { storage_prefix: b"foo".to_vec(), data: PhantomData::, pk_name: vec![], - de_fn: |_, _, kv| deserialize_kv::, u64>(kv), + de_fn_kv: |_, _, kv| deserialize_kv::, u64>(kv), + de_fn_v: |_, _, kv| deserialize_v(kv), }; // set some data, we care about "foo" prefix From c7d1723f5c3357221b5f9725538898a4a60d1a84 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 10 Dec 2021 23:18:12 +0100 Subject: [PATCH 002/631] Replace prefix() + range() by prefix_de() + range_raw() Remove prefix() --- contracts/cw1155-base/src/contract.rs | 8 +++--- contracts/cw20-base/src/enumerable.rs | 4 +-- contracts/cw20-ics20/src/contract.rs | 4 +-- contracts/cw3-fixed-multisig/src/contract.rs | 4 +-- contracts/cw3-flex-multisig/src/contract.rs | 4 +-- packages/storage-plus/src/map.rs | 27 ++++++++------------ packages/storage-plus/src/snapshot/map.rs | 4 --- packages/storage-plus/src/snapshot/mod.rs | 8 +++--- 8 files changed, 27 insertions(+), 36 deletions(-) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index d52940a7a..4c2296464 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -497,8 +497,8 @@ fn query_all_approvals( let start = start_after.map(|addr| Bound::exclusive(addr.as_ref())); let operators = APPROVES - .prefix(&owner) - .range(deps.storage, start, None, Order::Ascending) + .prefix_de(&owner) + .range_raw(deps.storage, start, None, Order::Ascending) .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) .take(limit) .map(parse_approval) @@ -516,8 +516,8 @@ fn query_tokens( let start = start_after.map(Bound::exclusive); let tokens = BALANCES - .prefix(&owner) - .range(deps.storage, start, None, Order::Ascending) + .prefix_de(&owner) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(k, _)| String::from_utf8(k).unwrap())) .collect::>()?; diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 2f97be5fa..1bdb46a94 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -19,8 +19,8 @@ pub fn query_all_allowances( let start = start_after.map(Bound::exclusive); let allowances: StdResult> = ALLOWANCES - .prefix(&owner_addr) - .range(deps.storage, start, None, Order::Ascending) + .prefix_de(&owner_addr) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (k, v) = item?; diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index a8834eb96..ca959f473 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -165,8 +165,8 @@ pub fn query_channel(deps: Deps, id: String) -> StdResult { let info = CHANNEL_INFO.load(deps.storage, &id)?; // this returns Vec<(outstanding, total)> let state: StdResult> = CHANNEL_STATE - .prefix(&id) - .range(deps.storage, None, None, Order::Ascending) + .prefix_de(&id) + .range_raw(deps.storage, None, None, Order::Ascending) .map(|r| { let (k, v) = r?; let denom = String::from_utf8(k)?; diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 287946334..ce739f702 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -386,8 +386,8 @@ fn list_votes( let start = start_after.map(Bound::exclusive); let votes: StdResult> = BALLOTS - .prefix(proposal_id) - .range(deps.storage, start, None, Order::Ascending) + .prefix_de(proposal_id) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, ballot) = item?; diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index eafc2b221..c1b3f695b 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -383,8 +383,8 @@ fn list_votes( let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); let votes: StdResult> = BALLOTS - .prefix(proposal_id) - .range(deps.storage, start, None, Order::Ascending) + .prefix_de(proposal_id) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (voter, ballot) = item?; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 2b623e82f..9058e8037 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -49,11 +49,6 @@ where ) } - #[cfg(feature = "iterator")] - pub fn prefix(&self, p: K::Prefix) -> Prefix, T> { - Prefix::new(self.namespace, &p.prefix()) - } - #[cfg(feature = "iterator")] pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { Prefix::new(self.namespace, &p.prefix()) @@ -611,8 +606,8 @@ mod test { // let's try to iterate over a prefix let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range(&store, None, None, Order::Ascending) + .prefix_de(b"owner") + .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -713,8 +708,8 @@ mod test { // let's iterate over a prefix let all: StdResult> = TRIPLE - .prefix((b"owner", 9)) - .range(&store, None, None, Order::Ascending) + .prefix_de((b"owner", 9)) + .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -981,8 +976,8 @@ mod test { // get all under one key let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range(&store, None, None, Order::Ascending) + .prefix_de(b"owner") + .range_raw(&store, None, None, Order::Ascending) .collect(); assert_eq!( all?, @@ -991,8 +986,8 @@ mod test { // Or ranges between two items (even reverse) let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range( + .prefix_de(b"owner") + .range_raw( &store, Some(Bound::Exclusive(b"spender1".to_vec())), Some(Bound::Inclusive(b"spender2".to_vec())), @@ -1021,8 +1016,8 @@ mod test { // typical range under one prefix as a control let fives = AGES - .prefix(5) - .range(&store, None, None, Order::Ascending) + .prefix_de(5) + .range_raw(&store, None, None, Order::Ascending) .collect::>>() .unwrap(); assert_eq!(fives.len(), 2); @@ -1119,7 +1114,7 @@ mod test { ); let keys: Vec<_> = AGES - .no_prefix() + .no_prefix_de() .keys_de(&store, None, None, Order::Ascending) .collect(); println!("keys: {:?}", keys); diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index fb5a4c864..87cfc703b 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -69,10 +69,6 @@ where self.primary.key(k) } - pub fn prefix(&self, p: K::Prefix) -> Prefix, T> { - self.primary.prefix(p) - } - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { self.primary.sub_prefix(p) } diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index d0418ce2c..e8a587d1f 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -87,8 +87,8 @@ where let start = Bound::inclusive(height); let first = self .changelog - .prefix(k.clone()) - .range(store, Some(start), None, Order::Ascending) + .prefix_de(k.clone()) + .range_raw(store, Some(start), None, Order::Ascending) .next() .transpose()?; if first.is_none() { @@ -146,8 +146,8 @@ where let start = Bound::inclusive_int(height); let first = self .changelog - .prefix(key) - .range(store, Some(start), None, Order::Ascending) + .prefix_de(key) + .range_raw(store, Some(start), None, Order::Ascending) .next(); if let Some(r) = first { From 7069f39b9b4459e13f51752e5e5a872ba25899a6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 10 Dec 2021 23:22:37 +0100 Subject: [PATCH 003/631] Replace sub_prefix() + range() by sub_prefix_de() + range_raw() Remove sub_prefix() --- packages/storage-plus/src/map.rs | 9 ++------- packages/storage-plus/src/snapshot/map.rs | 4 ---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 9058e8037..1e7471074 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -49,11 +49,6 @@ where ) } - #[cfg(feature = "iterator")] - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { - Prefix::new(self.namespace, &p.prefix()) - } - #[cfg(feature = "iterator")] pub(crate) fn no_prefix(&self) -> Prefix, T> { Prefix::new(self.namespace, &[]) @@ -723,8 +718,8 @@ mod test { // let's iterate over a sub prefix let all: StdResult> = TRIPLE - .sub_prefix(b"owner") - .range(&store, None, None, Order::Ascending) + .sub_prefix_de(b"owner") + .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 87cfc703b..9086083a6 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -69,10 +69,6 @@ where self.primary.key(k) } - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { - self.primary.sub_prefix(p) - } - fn no_prefix(&self) -> Prefix, T> { self.primary.no_prefix() } From 376cc58fad564121b90e996da92b4e9559069e6d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 10 Dec 2021 23:40:27 +0100 Subject: [PATCH 004/631] Replace no_prefix() + range() by no_prefix() + range_raw() --- packages/storage-plus/src/map.rs | 2 +- packages/storage-plus/src/snapshot/map.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 1e7471074..33526fd7c 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -164,7 +164,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } pub fn keys<'c>( diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 9086083a6..24b03ccc0 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -174,7 +174,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } } From e047a906ce2f873c8a3bae5b15cb4c071c3ae5ba Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 10 Dec 2021 23:45:58 +0100 Subject: [PATCH 005/631] Rename keys to keys_raw --- contracts/cw20-atomic-swap/src/state.rs | 2 +- contracts/cw20-base/src/enumerable.rs | 2 +- contracts/cw20-escrow/src/state.rs | 2 +- packages/storage-plus/src/indexed_map.rs | 2 +- packages/storage-plus/src/indexed_snapshot.rs | 2 +- packages/storage-plus/src/indexes/multi.rs | 6 +++--- packages/storage-plus/src/indexes/unique.rs | 2 +- packages/storage-plus/src/map.rs | 7 +++---- packages/storage-plus/src/prefix.rs | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/contracts/cw20-atomic-swap/src/state.rs b/contracts/cw20-atomic-swap/src/state.rs index ac67aa6b0..7df449e9d 100644 --- a/contracts/cw20-atomic-swap/src/state.rs +++ b/contracts/cw20-atomic-swap/src/state.rs @@ -32,7 +32,7 @@ pub fn all_swap_ids( limit: usize, ) -> StdResult> { SWAPS - .keys(storage, start, None, Order::Ascending) + .keys_raw(storage, start, None, Order::Ascending) .take(limit) .map(|k| String::from_utf8(k).map_err(|_| StdError::invalid_utf8("Parsing swap id"))) .collect() diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 1bdb46a94..319097ac3 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -45,7 +45,7 @@ pub fn query_all_accounts( let start = start_after.map(Bound::exclusive); let accounts: Result, _> = BALANCES - .keys(deps.storage, start, None, Order::Ascending) + .keys_raw(deps.storage, start, None, Order::Ascending) .map(String::from_utf8) .take(limit) .collect(); diff --git a/contracts/cw20-escrow/src/state.rs b/contracts/cw20-escrow/src/state.rs index 4539f826c..c09dcd3e2 100644 --- a/contracts/cw20-escrow/src/state.rs +++ b/contracts/cw20-escrow/src/state.rs @@ -95,7 +95,7 @@ pub const ESCROWS: Map<&str, Escrow> = Map::new("escrow"); /// This returns the list of ids for all registered escrows pub fn all_escrow_ids(storage: &dyn Storage) -> StdResult> { ESCROWS - .keys(storage, None, None, Order::Ascending) + .keys_raw(storage, None, None, Order::Ascending) .map(|k| String::from_utf8(k).map_err(|_| StdError::invalid_utf8("parsing escrow key"))) .collect() } diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 580182a31..aa6e0d8c7 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -828,7 +828,7 @@ mod test { map.idx .name .prefix(name.to_string()) - .keys(store, None, None, Order::Ascending) + .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 8b4470927..dc99fa3f5 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -819,7 +819,7 @@ mod test { map.idx .name .prefix(name.as_bytes().to_vec()) - .keys(store, None, None, Order::Ascending) + .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 1ee2373d2..44e99c819 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -180,14 +180,14 @@ where #[cfg(test)] pub fn count(&self, store: &dyn Storage, p: IK) -> usize { let prefix = self.prefix(p); - prefix.keys(store, None, None, Order::Ascending).count() + prefix.keys_raw(store, None, None, Order::Ascending).count() } #[cfg(test)] pub fn all_pks(&self, store: &dyn Storage, p: IK) -> Vec> { let prefix = self.prefix(p); prefix - .keys(store, None, None, Order::Ascending) + .keys_raw(store, None, None, Order::Ascending) .collect::>>() } @@ -226,7 +226,7 @@ where max: Option, order: Order, ) -> Box> + 'c> { - self.no_prefix().keys(store, min, max, order) + self.no_prefix().keys_raw(store, min, max, order) } /// While `range` over a `prefix` fixes the prefix to one element and iterates over the diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 922f3f647..7b02ea7c2 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -180,7 +180,7 @@ where max: Option, order: Order, ) -> Box> + 'c> { - self.no_prefix().keys(store, min, max, order) + self.no_prefix().keys_raw(store, min, max, order) } } diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 33526fd7c..568684834 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -167,7 +167,7 @@ where self.no_prefix().range_raw(store, min, max, order) } - pub fn keys<'c>( + pub fn keys_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -177,7 +177,7 @@ where where T: 'c, { - self.no_prefix().keys(store, min, max, order) + self.no_prefix().keys_raw(store, min, max, order) } } @@ -1019,8 +1019,7 @@ mod test { assert_eq!(fives, vec![(vec![7, 8, 9], 789), (vec![9, 8, 7], 987)]); let keys: Vec<_> = AGES - .no_prefix() - .keys(&store, None, None, Order::Ascending) + .keys_raw(&store, None, None, Order::Ascending) .collect(); println!("keys: {:?}", keys); diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 4356830c2..8a4335b25 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -182,7 +182,7 @@ where Box::new(mapped) } - pub fn keys<'a>( + pub fn keys_raw<'a>( &self, store: &'a dyn Storage, min: Option, From d0fd20e283c7e5dd98d619f4c6a99910df8eb241 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 07:33:51 +0100 Subject: [PATCH 006/631] Rename range to range_raw --- contracts/cw1-subkeys/src/contract.rs | 4 ++-- contracts/cw1155-base/src/contract.rs | 2 +- contracts/cw20-ics20/src/contract.rs | 2 +- contracts/cw3-fixed-multisig/src/contract.rs | 6 +++--- contracts/cw3-flex-multisig/src/contract.rs | 4 ++-- packages/controllers/src/claim.rs | 2 +- packages/multi-test/src/wasm.rs | 2 +- packages/storage-plus/src/map.rs | 22 +++++++++++++------- packages/storage-plus/src/snapshot/mod.rs | 2 +- packages/utils/src/pagination.rs | 4 ++-- 10 files changed, 28 insertions(+), 22 deletions(-) diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index f20a65ec6..84304be68 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -410,7 +410,7 @@ pub fn query_all_allowances( let start = start_after.map(Bound::exclusive); let res: StdResult> = ALLOWANCES - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .filter(|item| { if let Ok((_, allow)) = item { !allow.expires.is_expired(&env.block) @@ -442,7 +442,7 @@ pub fn query_all_permissions( let start = start_after.map(Bound::exclusive); let res: StdResult> = PERMISSIONS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { item.and_then(|(k, perm)| { diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 4c2296464..75c6ebbdf 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -532,7 +532,7 @@ fn query_all_tokens( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); let tokens = TOKENS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(k, _)| String::from_utf8(k).unwrap())) .collect::>()?; diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index ca959f473..d3c3f3f0b 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -152,7 +152,7 @@ fn query_port(deps: Deps) -> StdResult { fn query_list(deps: Deps) -> StdResult { let channels: StdResult> = CHANNEL_INFO - .range(deps.storage, None, None, Order::Ascending) + .range_raw(deps.storage, None, None, Order::Ascending) .map(|r| r.map(|(_, v)| v)) .collect(); Ok(ListChannelsResponse { diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index ce739f702..f99882a1d 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -316,7 +316,7 @@ fn list_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|p| map_proposal(&env.block, &threshold, p)) .collect(); @@ -339,7 +339,7 @@ fn reverse_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let end = start_before.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(deps.storage, None, end, Order::Descending) + .range_raw(deps.storage, None, end, Order::Descending) .take(limit) .map(|p| map_proposal(&env.block, &threshold, p)) .collect(); @@ -417,7 +417,7 @@ fn list_voters( let start = start_after.map(Bound::exclusive); let voters: StdResult> = VOTERS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, weight) = item?; diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index c1b3f695b..b508331b4 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -318,7 +318,7 @@ fn list_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|p| map_proposal(&env.block, p)) .collect(); @@ -335,7 +335,7 @@ fn reverse_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let end = start_before.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range(deps.storage, None, end, Order::Descending) + .range_raw(deps.storage, None, end, Order::Descending) .take(limit) .map(|p| map_proposal(&env.block, p)) .collect(); diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index 693fd2e7e..b4d1b502c 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -118,7 +118,7 @@ mod test { assert_eq!( claims .0 - .range(&deps.storage, None, None, Order::Ascending) + .range_raw(&deps.storage, None, None, Order::Ascending) .collect::>>() .unwrap() .len(), diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 9b98bf509..1e1ef5872 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -791,7 +791,7 @@ where fn next_address(&self, storage: &dyn Storage) -> Addr { // FIXME: quite inefficient if we actually had 100s of contracts let count = CONTRACTS - .range(storage, None, None, Order::Ascending) + .range_raw(storage, None, None, Order::Ascending) .count(); // we make this longer so it is not rejected by tests Addr::unchecked(format!("Contract #{}", count.to_string())) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 568684834..5917a09c7 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -154,7 +154,7 @@ where Box::new(mapped) } - pub fn range<'c>( + pub fn range_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -412,7 +412,9 @@ mod test { 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: StdResult> = PEOPLE + .range_raw(&store, None, None, Order::Ascending) + .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); assert_eq!( @@ -425,7 +427,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = PEOPLE - .range( + .range_raw( &store, Some(Bound::Inclusive(b"j".to_vec())), None, @@ -441,7 +443,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = PEOPLE - .range( + .range_raw( &store, Some(Bound::Inclusive(b"jo".to_vec())), None, @@ -586,7 +588,7 @@ mod test { // let's try to iterate! let all: StdResult> = ALLOWANCE - .range(&store, None, None, Order::Ascending) + .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -676,7 +678,9 @@ mod test { .unwrap(); // let's try to iterate! - let all: StdResult> = TRIPLE.range(&store, None, None, Order::Ascending).collect(); + let all: StdResult> = TRIPLE + .range_raw(&store, None, None, Order::Ascending) + .collect(); let all = all.unwrap(); assert_eq!(4, all.len()); assert_eq!( @@ -947,7 +951,9 @@ mod test { PEOPLE.save(&mut store, b"jim", &data2)?; // iterate over them all - let all: StdResult> = PEOPLE.range(&store, None, None, Order::Ascending).collect(); + let all: StdResult> = PEOPLE + .range_raw(&store, None, None, Order::Ascending) + .collect(); assert_eq!( all?, vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())] @@ -955,7 +961,7 @@ mod test { // or just show what is after jim let all: StdResult> = PEOPLE - .range( + .range_raw( &store, Some(Bound::Exclusive(b"jim".to_vec())), None, diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index e8a587d1f..cdf3abc71 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -79,7 +79,7 @@ where // most recent checkpoint let checkpoint = self .checkpoints - .range(store, None, None, Order::Descending) + .range_raw(store, None, None, Order::Descending) .next() .transpose()?; if let Some((height, _)) = checkpoint { diff --git a/packages/utils/src/pagination.rs b/packages/utils/src/pagination.rs index 615993561..b346fb776 100644 --- a/packages/utils/src/pagination.rs +++ b/packages/utils/src/pagination.rs @@ -73,7 +73,7 @@ mod test { let start = calc_range_start(start_after).map(Bound::exclusive); let holders: Vec<(String, usize)> = HOLDERS - .range(&deps.storage, start, None, Order::Ascending) + .range_raw(&deps.storage, start, None, Order::Ascending) .map(deser_holder_kv) .take(LIMIT) .collect(); @@ -102,7 +102,7 @@ mod test { let end = calc_range_end(end_before).map(Bound::exclusive); let holders: Vec<(String, usize)> = HOLDERS - .range(&deps.storage, None, end, Order::Descending) + .range_raw(&deps.storage, None, end, Order::Descending) .map(deser_holder_kv) .take(LIMIT) .collect(); From 05d185516cb2a374ded016a968e543cecd3a8798 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 07:44:54 +0100 Subject: [PATCH 007/631] Replace no_prefix() + range() by no_prefix() + range_raw() in indexes --- packages/storage-plus/src/indexes/multi.rs | 2 +- packages/storage-plus/src/indexes/unique.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 44e99c819..3d29a49df 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -216,7 +216,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } pub fn keys<'c>( diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 7b02ea7c2..f579cf8bd 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -170,7 +170,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } pub fn keys<'c>( From 57c470fe6e60ff76b4ba44fc9f08ce5665ae56a1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 08:28:12 +0100 Subject: [PATCH 008/631] Replace no_prefix() + range() by no_prefix() + range_raw() in indexed maps --- packages/storage-plus/src/indexed_map.rs | 2 +- packages/storage-plus/src/indexed_snapshot.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index aa6e0d8c7..3b0e59d40 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -164,7 +164,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } } diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index dc99fa3f5..1b4e6b206 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -209,7 +209,7 @@ where where T: 'c, { - self.no_prefix().range(store, min, max, order) + self.no_prefix().range_raw(store, min, max, order) } } From 249b35f5755c6d222901abf98a545c2305879f8f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 08:42:53 +0100 Subject: [PATCH 009/631] Replace prefix() + range() by prefix_de() + range_raw() in unique index Remove UniqueIndex::prefix() --- packages/storage-plus/src/indexed_map.rs | 4 ++-- packages/storage-plus/src/indexed_snapshot.rs | 4 ++-- packages/storage-plus/src/indexes/unique.rs | 10 ---------- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 3b0e59d40..cab7ed47d 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -937,8 +937,8 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 1b4e6b206..c62d2ff15 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -925,8 +925,8 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index f579cf8bd..1075746e1 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -112,16 +112,6 @@ where k.joined_key() } - pub fn prefix(&self, p: IK::Prefix) -> Prefix, T> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - &[], - |_, _, kv| deserialize_unique_v(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } - pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, From a2b64b8beea8166a2f4628b82426ab738b00295a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 08:44:10 +0100 Subject: [PATCH 010/631] Remove UniqueIndex::sub_prefix --- packages/storage-plus/src/indexes/unique.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 1075746e1..dc1a3e45d 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -112,16 +112,6 @@ where k.joined_key() } - pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix, T> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - &[], - |_, _, kv| deserialize_unique_v(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } - fn no_prefix(&self) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, From 40a587f2ba86422e9016956e3e3801e45065825b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 09:10:57 +0100 Subject: [PATCH 011/631] Replace prefix() + range() by prefix_de() + range_raw() in multi index Remove MultiIndex::prefix() Adjust MultiIndex::no_prefix() trait bounds --- packages/storage-plus/src/indexed_map.rs | 26 ++++++++-------- packages/storage-plus/src/indexed_snapshot.rs | 26 ++++++++-------- packages/storage-plus/src/indexes/multi.rs | 31 +++++++++---------- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index cab7ed47d..901694853 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -414,8 +414,8 @@ mod test { let count = map .idx .name - .prefix("Maria".to_string()) - .range(&store, None, None, Order::Ascending) + .prefix_de("Maria".to_string()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(2, count); @@ -423,8 +423,8 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix("Maria".to_string()) - .range(&store, None, None, Order::Ascending) + .prefix_de("Maria".to_string()) + .range_raw(&store, None, None, Order::Ascending) .collect::>() .unwrap(); assert_eq!(2, marias.len()); @@ -436,8 +436,8 @@ mod test { let count = map .idx .name - .prefix("Marib".to_string()) - .range(&store, None, None, Order::Ascending) + .prefix_de("Marib".to_string()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -445,8 +445,8 @@ mod test { let count = map .idx .name - .prefix("Mari`".to_string()) - .range(&store, None, None, Order::Ascending) + .prefix_de("Mari`".to_string()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -454,8 +454,8 @@ mod test { let count = map .idx .name - .prefix("Maria5".to_string()) - .range(&store, None, None, Order::Ascending) + .prefix_de("Maria5".to_string()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -560,8 +560,8 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix("Maria".to_string()) - .range(&store, None, None, Order::Descending) + .prefix_de("Maria".to_string()) + .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -827,7 +827,7 @@ mod test { -> usize { map.idx .name - .prefix(name.to_string()) + .prefix_de(name.to_string()) .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index c62d2ff15..c022322be 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -430,8 +430,8 @@ mod test { let count = map .idx .name - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(2, count); @@ -439,8 +439,8 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .collect::>() .unwrap(); assert_eq!(2, marias.len()); @@ -452,8 +452,8 @@ mod test { let count = map .idx .name - .prefix(b"Marib".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Marib".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -461,8 +461,8 @@ mod test { let count = map .idx .name - .prefix(b"Mari`".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Mari`".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -470,8 +470,8 @@ mod test { let count = map .idx .name - .prefix(b"Maria5".to_vec()) - .range(&store, None, None, Order::Ascending) + .prefix_de(b"Maria5".to_vec()) + .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -532,8 +532,8 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) + .prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -818,7 +818,7 @@ mod test { -> usize { map.idx .name - .prefix(name.as_bytes().to_vec()) + .prefix_de(name.as_bytes().to_vec()) .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 3d29a49df..2e0dbbcd6 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -143,16 +143,23 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - pub fn prefix(&self, p: IK) -> Prefix, T> { + fn no_prefix(&self) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, - &p.prefix(), + &[], self.pk_namespace, deserialize_multi_v, deserialize_multi_v, ) } +} +impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> +where + PK: PrimaryKey<'a> + KeyDeserialize, + T: Serialize + DeserializeOwned + Clone, + IK: PrimaryKey<'a> + Prefixer<'a>, +{ pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, @@ -163,29 +170,19 @@ where ) } - fn no_prefix(&self) -> Prefix, T> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &[], - self.pk_namespace, - deserialize_multi_v, - deserialize_multi_v, - ) - } - pub fn index_key(&self, k: IK) -> Vec { k.joined_extra_key(b"") } #[cfg(test)] pub fn count(&self, store: &dyn Storage, p: IK) -> usize { - let prefix = self.prefix(p); + let prefix = self.prefix_de(p); prefix.keys_raw(store, None, None, Order::Ascending).count() } #[cfg(test)] pub fn all_pks(&self, store: &dyn Storage, p: IK) -> Vec> { - let prefix = self.prefix(p); + let prefix = self.prefix_de(p); prefix .keys_raw(store, None, None, Order::Ascending) .collect::>>() @@ -193,8 +190,10 @@ where #[cfg(test)] pub fn all_items(&self, store: &dyn Storage, p: IK) -> StdResult>> { - let prefix = self.prefix(p); - prefix.range(store, None, None, Order::Ascending).collect() + let prefix = self.prefix_de(p); + prefix + .range_raw(store, None, None, Order::Ascending) + .collect() } } From a2112abd3165fab5e308305899e95197831ba517 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 09:15:42 +0100 Subject: [PATCH 012/631] Replace sub_prefix() + range() by sub_prefix_de() + range_raw() in multi index Remove MultiIndex::sub_prefix --- packages/storage-plus/src/indexed_map.rs | 4 ++-- packages/storage-plus/src/indexed_snapshot.rs | 4 ++-- packages/storage-plus/src/indexes/multi.rs | 10 ---------- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 901694853..592becca0 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -676,8 +676,8 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) + .sub_prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index c022322be..ff9655662 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -657,8 +657,8 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) + .sub_prefix_de(b"Maria".to_vec()) + .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 2e0dbbcd6..ee574f45b 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -160,16 +160,6 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix, T> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - self.pk_namespace, - deserialize_multi_v, - deserialize_multi_v, - ) - } - pub fn index_key(&self, k: IK) -> Vec { k.joined_extra_key(b"") } From 69d26042860990021d81ae0922c3167b8e147f07 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 09:30:20 +0100 Subject: [PATCH 013/631] Remove Prefix::range --- packages/storage-plus/src/map.rs | 2 +- packages/storage-plus/src/prefix.rs | 44 +++++++++-------------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 5917a09c7..c1f2e4b4d 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -1104,7 +1104,7 @@ mod test { // typical range under one prefix as a control let fives = AGES .prefix_de(5) - .range(&store, None, None, Order::Ascending) + .range_de(&store, None, None, Order::Ascending) .collect::>>() .unwrap(); assert_eq!(fives.len(), 2); diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 8a4335b25..f522de923 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -164,24 +164,6 @@ where Box::new(mapped) } - pub fn range<'a>( - &self, - store: &'a dyn Storage, - min: Option, - max: Option, - order: Order, - ) -> Box> + 'a> - where - T: 'a, - K::Output: 'a, - { - 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_raw<'a>( &self, store: &'a dyn Storage, @@ -368,16 +350,18 @@ 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, None, None, Order::Ascending).collect(); + let res: StdResult> = prefix + .range_raw(&store, None, None, Order::Ascending) + .collect(); assert_eq!(&expected, &res.unwrap()); let res: StdResult> = prefix - .range(&store, None, None, Order::Descending) + .range_raw(&store, None, None, Order::Descending) .collect(); assert_eq!(&expected_reversed, &res.unwrap()); // now let's check some ascending ranges let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Inclusive(b"ra".to_vec())), None, @@ -387,7 +371,7 @@ mod test { assert_eq!(&expected[1..], res.unwrap().as_slice()); // skip excluded let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Exclusive(b"ra".to_vec())), None, @@ -397,7 +381,7 @@ mod test { assert_eq!(&expected[2..], res.unwrap().as_slice()); // if we exclude something a little lower, we get matched let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Exclusive(b"r".to_vec())), None, @@ -408,7 +392,7 @@ mod test { // now let's check some descending ranges let res: StdResult> = prefix - .range( + .range_raw( &store, None, Some(Bound::Inclusive(b"ra".to_vec())), @@ -418,7 +402,7 @@ mod test { assert_eq!(&expected_reversed[1..], res.unwrap().as_slice()); // skip excluded let res: StdResult> = prefix - .range( + .range_raw( &store, None, Some(Bound::Exclusive(b"ra".to_vec())), @@ -428,7 +412,7 @@ mod test { assert_eq!(&expected_reversed[2..], res.unwrap().as_slice()); // if we exclude something a little higher, we get matched let res: StdResult> = prefix - .range( + .range_raw( &store, None, Some(Bound::Exclusive(b"rb".to_vec())), @@ -439,7 +423,7 @@ mod test { // now test when both sides are set let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Inclusive(b"ra".to_vec())), Some(Bound::Exclusive(b"zi".to_vec())), @@ -449,7 +433,7 @@ mod test { assert_eq!(&expected[1..2], res.unwrap().as_slice()); // and descending let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Inclusive(b"ra".to_vec())), Some(Bound::Exclusive(b"zi".to_vec())), @@ -459,7 +443,7 @@ mod test { assert_eq!(&expected[1..2], res.unwrap().as_slice()); // Include both sides let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Inclusive(b"ra".to_vec())), Some(Bound::Inclusive(b"zi".to_vec())), @@ -469,7 +453,7 @@ mod test { assert_eq!(&expected_reversed[..2], res.unwrap().as_slice()); // Exclude both sides let res: StdResult> = prefix - .range( + .range_raw( &store, Some(Bound::Exclusive(b"ra".to_vec())), Some(Bound::Exclusive(b"zi".to_vec())), From e6e1926d342487504ff4ffd6f91f65d4e2179e32 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 10:07:29 +0100 Subject: [PATCH 014/631] Rename keys/range to keys_raw/range_raw in indexes --- packages/storage-plus/src/indexed_map.rs | 8 ++++---- packages/storage-plus/src/indexed_snapshot.rs | 2 +- packages/storage-plus/src/indexes/multi.rs | 4 ++-- packages/storage-plus/src/indexes/unique.rs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 592becca0..bc9fb93a8 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -469,7 +469,7 @@ mod test { let count = map .idx .name - .range(&store, Some(Bound::inclusive(key)), None, Order::Ascending) + .range_raw(&store, Some(Bound::inclusive(key)), None, Order::Ascending) .count(); // gets from the first "Maria" until the end assert_eq!(4, count); @@ -484,7 +484,7 @@ mod test { let count = map .idx .name - .range(&store, Some(Bound::exclusive(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); @@ -497,7 +497,7 @@ mod test { let count = map .idx .age - .range( + .range_raw( &store, Some(Bound::inclusive(age_key)), None, @@ -871,7 +871,7 @@ mod test { let res: StdResult> = map .idx .age - .range(&store, None, None, Order::Ascending) + .range_raw(&store, None, None, Order::Ascending) .collect(); let ages = res.unwrap(); diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index ff9655662..1015333f4 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -863,7 +863,7 @@ mod test { let res: StdResult> = map .idx .age - .range(&store, None, None, Order::Ascending) + .range_raw(&store, None, None, Order::Ascending) .collect(); let ages = res.unwrap(); diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index ee574f45b..b1453752f 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -195,7 +195,7 @@ where { // 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<'c>( + pub fn range_raw<'c>( &'c self, store: &'c dyn Storage, min: Option, @@ -208,7 +208,7 @@ where self.no_prefix().range_raw(store, min, max, order) } - pub fn keys<'c>( + pub fn keys_raw<'c>( &'c self, store: &'c dyn Storage, min: Option, diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index dc1a3e45d..dcdb40744 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -140,7 +140,7 @@ where { // 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<'c>( + pub fn range_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -153,7 +153,7 @@ where self.no_prefix().range_raw(store, min, max, order) } - pub fn keys<'c>( + pub fn keys_raw<'c>( &self, store: &'c dyn Storage, min: Option, From 938b897dadad520b5b458af62ab31f769a19f19d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 10:18:58 +0100 Subject: [PATCH 015/631] Rename keys/range to keys_raw/range_raw in indexed maps --- packages/storage-plus/src/indexed_map.rs | 12 +++++++++++- packages/storage-plus/src/indexed_snapshot.rs | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index bc9fb93a8..5d39e6cfb 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -154,7 +154,7 @@ where { // 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<'c>( + pub fn range_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -166,6 +166,16 @@ where { self.no_prefix().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().keys_raw(store, min, max, order) + } } #[cfg(feature = "iterator")] diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 1015333f4..4b291a7d3 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -199,7 +199,7 @@ where { // 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<'c>( + pub fn range_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -211,6 +211,16 @@ where { self.no_prefix().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().keys_raw(store, min, max, order) + } } #[cfg(feature = "iterator")] From 0e1af087216c96b2967bbb2d92b18ddbbe1acfa1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 12:53:25 +0100 Subject: [PATCH 016/631] Rename keys/range to keys_raw/range_raw in snampshot map --- contracts/cw4-group/src/contract.rs | 2 +- contracts/cw4-stake/src/contract.rs | 2 +- packages/storage-plus/src/snapshot/map.rs | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 1600d020e..e0a34d3f1 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -193,7 +193,7 @@ fn list_members( let start = addr.map(|addr| Bound::exclusive(addr.to_string())); let members: StdResult> = MEMBERS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, weight) = item?; diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 2b4d86774..20aa3b6f2 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -342,7 +342,7 @@ fn list_members( let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); let members: StdResult> = MEMBERS - .range(deps.storage, start, None, Order::Ascending) + .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { let (key, weight) = item?; diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 24b03ccc0..90e84e5fd 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -164,7 +164,7 @@ where { // 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<'c>( + pub fn range_raw<'c>( &self, store: &'c dyn Storage, min: Option, @@ -176,6 +176,19 @@ where { self.no_prefix().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().keys_raw(store, min, max, order) + } } #[cfg(feature = "iterator")] From 3542f03f164c6352a810fb1e75127431168c4d6f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 12:54:39 +0100 Subject: [PATCH 017/631] Remove sub_/prefix() from indexed maps --- packages/storage-plus/src/indexed_map.rs | 10 ---------- packages/storage-plus/src/indexed_snapshot.rs | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 5d39e6cfb..8fb32463e 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -129,16 +129,6 @@ where self.primary.may_load(store, key) } - // use prefix to scan -> range - pub fn prefix(&self, p: K::Prefix) -> Prefix, T> { - Prefix::new(self.pk_namespace, &p.prefix()) - } - - // use sub_prefix to scan -> range - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { - Prefix::new(self.pk_namespace, &p.prefix()) - } - // use no_prefix to scan -> range fn no_prefix(&self) -> Prefix, T> { Prefix::new(self.pk_namespace, &[]) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 4b291a7d3..344c1eb81 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -174,16 +174,6 @@ where self.primary.may_load(store, key) } - // use prefix to scan -> range - pub fn prefix(&self, p: K::Prefix) -> Prefix, T> { - Prefix::new(self.pk_namespace, &p.prefix()) - } - - // use sub_prefix to scan -> range - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix, T> { - Prefix::new(self.pk_namespace, &p.prefix()) - } - // use no_prefix to scan -> range pub fn no_prefix(&self) -> Prefix, T> { Prefix::new(self.pk_namespace, &[]) From 6fc2608d7e8eb46d5b1ba022f3baea5f26030b95 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 12:58:27 +0100 Subject: [PATCH 018/631] Rename prefix_range to prefix_range_raw --- packages/storage-plus/src/map.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index c1f2e4b4d..08581f170 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -138,7 +138,7 @@ where /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range<'c>( + pub fn prefix_range_raw<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -1031,7 +1031,7 @@ mod test { // using inclusive bounds both sides let include = AGES - .prefix_range( + .prefix_range_raw( &store, Some(PrefixBound::inclusive(3u32)), Some(PrefixBound::inclusive(7u32)), @@ -1045,7 +1045,7 @@ mod test { // using exclusive bounds both sides let exclude = AGES - .prefix_range( + .prefix_range_raw( &store, Some(PrefixBound::exclusive(3u32)), Some(PrefixBound::exclusive(7u32)), @@ -1059,7 +1059,7 @@ mod test { // using inclusive in descending let include = AGES - .prefix_range( + .prefix_range_raw( &store, Some(PrefixBound::inclusive(3u32)), Some(PrefixBound::inclusive(5u32)), @@ -1073,7 +1073,7 @@ mod test { // using exclusive in descending let include = AGES - .prefix_range( + .prefix_range_raw( &store, Some(PrefixBound::exclusive(2u32)), Some(PrefixBound::exclusive(5u32)), From 8a0d2eb73844b9621edf807b868d32389cfd35a4 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 13:03:09 +0100 Subject: [PATCH 019/631] Rename prefix_range to prefix_range_raw in indexed map --- packages/storage-plus/src/indexed_map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 8fb32463e..f703bcbde 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -180,7 +180,7 @@ where /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range<'c>( + pub fn prefix_range_raw<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -1429,7 +1429,7 @@ mod test { let items: Vec<_> = map .idx .secondary - .prefix_range( + .prefix_range_raw( &store, None, Some(PrefixBound::inclusive(1u64)), From d58272896dabfa2078ac8f9f796268384e243b56 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 13:03:50 +0100 Subject: [PATCH 020/631] Rename prefix_range to prefix_range_raw in multi index --- packages/storage-plus/src/indexes/multi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index b1453752f..48822878e 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -224,7 +224,7 @@ where /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range<'c>( + pub fn prefix_range_raw<'c>( &'c self, store: &'c dyn Storage, min: Option>, From 2f6b4cb3bdeb5cf418360ecbae3e8bcde79e3361 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 13:30:27 +0100 Subject: [PATCH 021/631] Remove useless dereference --- 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 f522de923..5ce9bf159 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -160,7 +160,7 @@ 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)); + .map(move |kv| (de_fn)(store, &pk_name, kv)); Box::new(mapped) } @@ -190,7 +190,7 @@ 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)); + .map(move |kv| (de_fn)(store, &pk_name, kv)); Box::new(mapped) } @@ -208,7 +208,7 @@ 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).map(|(k, _)| Ok(k))) + .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))) .flatten(); Box::new(mapped) } From bb3137c9590d74ce8d9a903d5e1d02334c97ec2a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 13:33:52 +0100 Subject: [PATCH 022/631] Rename keys_/range_de to keys/range in Prefix --- packages/storage-plus/src/indexed_map.rs | 18 +++++++++--------- packages/storage-plus/src/indexed_snapshot.rs | 14 +++++++------- packages/storage-plus/src/indexes/multi.rs | 4 ++-- packages/storage-plus/src/indexes/unique.rs | 4 ++-- packages/storage-plus/src/map.rs | 14 +++++++------- packages/storage-plus/src/prefix.rs | 4 ++-- packages/storage-plus/src/snapshot/map.rs | 8 ++++---- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index f703bcbde..89d0388c0 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -255,7 +255,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -269,7 +269,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } fn no_prefix_de(&self) -> Prefix { @@ -617,7 +617,7 @@ mod test { .idx .name .prefix_de("Maria".to_string()) - .range_de(&store, None, None, Order::Descending) + .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -738,7 +738,7 @@ mod test { .idx .name_age .sub_prefix_de(b"Maria".to_vec()) - .range_de(&store, None, None, Order::Descending) + .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -967,7 +967,7 @@ mod test { .idx .name_lastname .prefix_de(b"Maria".to_vec()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); @@ -1041,7 +1041,7 @@ mod test { // type checks let all: StdResult> = map .prefix_de(()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!( @@ -1100,7 +1100,7 @@ mod test { // let's prefix and iterate let result: StdResult> = map .prefix_de("2") - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); assert_eq!( @@ -1155,7 +1155,7 @@ mod test { // let's prefix and iterate let result: StdResult> = map .prefix_de(("1", "2")) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); assert_eq!(result, [("5628".to_string(), data2),]); @@ -1207,7 +1207,7 @@ mod test { // let's sub-prefix and iterate let result: StdResult> = map .sub_prefix_de("1") - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); assert_eq!( diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 344c1eb81..415cac5cd 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -271,7 +271,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -285,7 +285,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } fn no_prefix_de(&self) -> Prefix { @@ -593,7 +593,7 @@ mod test { .idx .name .prefix_de(b"Maria".to_vec()) - .range_de(&store, None, None, Order::Descending) + .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -724,7 +724,7 @@ mod test { .idx .name_age .sub_prefix_de(b"Maria".to_vec()) - .range_de(&store, None, None, Order::Descending) + .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); let count = marias.len(); @@ -955,7 +955,7 @@ mod test { .idx .name_lastname .prefix_de(b"Maria".to_vec()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); @@ -1029,7 +1029,7 @@ mod test { // type checks let all: StdResult> = map .prefix_de(()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!( @@ -1056,7 +1056,7 @@ mod test { // type checks let all: StdResult> = map .sub_prefix_de(()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!( diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 48822878e..99f46eaae 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -312,7 +312,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -326,7 +326,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } fn no_prefix_de(&self) -> Prefix { diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index dcdb40744..38adff44a 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -207,7 +207,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -221,7 +221,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } pub fn prefix_de(&self, p: IK::Prefix) -> Prefix { diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 08581f170..19818d343 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -222,7 +222,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -236,7 +236,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } fn no_prefix_de(&self) -> Prefix { @@ -648,7 +648,7 @@ mod test { // let's try to iterate over a prefix_de let all: StdResult> = ALLOWANCE .prefix_de(b"owner") - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -776,7 +776,7 @@ mod test { // let's iterate over a sub_prefix_de let all: StdResult> = TRIPLE .sub_prefix_de(b"owner") - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -792,7 +792,7 @@ mod test { // let's iterate over a prefix_de let all: StdResult> = TRIPLE .prefix_de((b"owner", 9)) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -1104,7 +1104,7 @@ mod test { // typical range under one prefix as a control let fives = AGES .prefix_de(5) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect::>>() .unwrap(); assert_eq!(fives.len(), 2); @@ -1115,7 +1115,7 @@ mod test { let keys: Vec<_> = AGES .no_prefix_de() - .keys_de(&store, None, None, Order::Ascending) + .keys(&store, None, None, Order::Ascending) .collect(); println!("keys: {:?}", keys); diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 5ce9bf159..5c210052a 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -176,7 +176,7 @@ where Box::new(mapped) } - pub fn range_de<'a>( + pub fn range<'a>( &self, store: &'a dyn Storage, min: Option, @@ -194,7 +194,7 @@ where Box::new(mapped) } - pub fn keys_de<'a>( + pub fn keys<'a>( &self, store: &'a dyn Storage, min: Option, diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 90e84e5fd..8f50acaf6 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -232,7 +232,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range_de(store, min, max, order) + self.no_prefix_de().range(store, min, max, order) } pub fn keys_de<'c>( @@ -246,7 +246,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys_de(store, min, max, order) + self.no_prefix_de().keys(store, min, max, order) } pub fn prefix_de(&self, p: K::Prefix) -> Prefix { @@ -557,7 +557,7 @@ mod tests { // let's prefix and iterate let all: StdResult> = EVERY_COMPOSITE_KEY .prefix_de("C") - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(1, all.len()); @@ -577,7 +577,7 @@ mod tests { // sub_prefix_de type checks let all: StdResult> = EVERY_COMPOSITE_KEY .sub_prefix_de(()) - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); From e06eb1456aef2ea6dc33dc14c277d73e85e00856 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:09:02 +0100 Subject: [PATCH 023/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in Map --- contracts/cw1155-base/src/contract.rs | 4 +- contracts/cw20-base/src/enumerable.rs | 2 +- contracts/cw20-ics20/src/contract.rs | 2 +- contracts/cw3-fixed-multisig/src/contract.rs | 2 +- contracts/cw3-flex-multisig/src/contract.rs | 2 +- packages/storage-plus/src/map.rs | 67 +++++++++----------- packages/storage-plus/src/snapshot/mod.rs | 4 +- 7 files changed, 38 insertions(+), 45 deletions(-) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 75c6ebbdf..74291b0f1 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -497,7 +497,7 @@ fn query_all_approvals( let start = start_after.map(|addr| Bound::exclusive(addr.as_ref())); let operators = APPROVES - .prefix_de(&owner) + .prefix(&owner) .range_raw(deps.storage, start, None, Order::Ascending) .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) .take(limit) @@ -516,7 +516,7 @@ fn query_tokens( let start = start_after.map(Bound::exclusive); let tokens = BALANCES - .prefix_de(&owner) + .prefix(&owner) .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(k, _)| String::from_utf8(k).unwrap())) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 319097ac3..7b6c526c8 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -19,7 +19,7 @@ pub fn query_all_allowances( let start = start_after.map(Bound::exclusive); let allowances: StdResult> = ALLOWANCES - .prefix_de(&owner_addr) + .prefix(&owner_addr) .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index d3c3f3f0b..03a806102 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -165,7 +165,7 @@ pub fn query_channel(deps: Deps, id: String) -> StdResult { let info = CHANNEL_INFO.load(deps.storage, &id)?; // this returns Vec<(outstanding, total)> let state: StdResult> = CHANNEL_STATE - .prefix_de(&id) + .prefix(&id) .range_raw(deps.storage, None, None, Order::Ascending) .map(|r| { let (k, v) = r?; diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index f99882a1d..48a600834 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -386,7 +386,7 @@ fn list_votes( let start = start_after.map(Bound::exclusive); let votes: StdResult> = BALLOTS - .prefix_de(proposal_id) + .prefix(proposal_id) .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index b508331b4..c7293d99c 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -383,7 +383,7 @@ fn list_votes( let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); let votes: StdResult> = BALLOTS - .prefix_de(proposal_id) + .prefix(proposal_id) .range_raw(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 19818d343..602a1dc59 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -115,11 +115,11 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a>, { - pub fn sub_prefix_de(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.namespace, &p.prefix()) } - pub fn prefix_de(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.namespace, &p.prefix()) } } @@ -187,13 +187,13 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a> + KeyDeserialize, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -211,7 +211,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -225,7 +225,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, @@ -474,9 +474,7 @@ mod test { PEOPLE.save(&mut store, b"jim", &data2).unwrap(); // let's try to iterate! - let all: StdResult> = PEOPLE - .range_de(&store, None, 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!( @@ -489,7 +487,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = PEOPLE - .range_de( + .range( &store, Some(Bound::Inclusive(b"j".to_vec())), None, @@ -505,7 +503,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = PEOPLE - .range_de( + .range( &store, Some(Bound::Inclusive(b"jo".to_vec())), None, @@ -537,7 +535,7 @@ mod test { // let's try to iterate! let all: StdResult> = PEOPLE_ID - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -545,7 +543,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = PEOPLE_ID - .range_de( + .range( &store, Some(Bound::inclusive_int(56u32)), None, @@ -558,7 +556,7 @@ mod test { // let's try to iterate over a more restrictive range let all: StdResult> = PEOPLE_ID - .range_de( + .range( &store, Some(Bound::inclusive_int(57u32)), None, @@ -603,7 +601,7 @@ mod test { // let's try to iterate over a prefix let all: StdResult> = ALLOWANCE - .prefix_de(b"owner") + .prefix(b"owner") .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -632,7 +630,7 @@ mod test { // let's try to iterate! let all: StdResult> = ALLOWANCE - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); @@ -647,7 +645,7 @@ mod test { // let's try to iterate over a prefix_de let all: StdResult> = ALLOWANCE - .prefix_de(b"owner") + .prefix(b"owner") .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -707,7 +705,7 @@ mod test { // let's iterate over a prefix let all: StdResult> = TRIPLE - .prefix_de((b"owner", 9)) + .prefix((b"owner", 9)) .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -722,7 +720,7 @@ mod test { // let's iterate over a sub prefix let all: StdResult> = TRIPLE - .sub_prefix_de(b"owner") + .sub_prefix(b"owner") .range_raw(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -758,9 +756,7 @@ mod test { .unwrap(); // let's try to iterate! - let all: StdResult> = TRIPLE - .range_de(&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!( @@ -775,7 +771,7 @@ mod test { // let's iterate over a sub_prefix_de let all: StdResult> = TRIPLE - .sub_prefix_de(b"owner") + .sub_prefix(b"owner") .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -791,7 +787,7 @@ mod test { // let's iterate over a prefix_de let all: StdResult> = TRIPLE - .prefix_de((b"owner", 9)) + .prefix((b"owner", 9)) .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -977,7 +973,7 @@ mod test { // get all under one key let all: StdResult> = ALLOWANCE - .prefix_de(b"owner") + .prefix(b"owner") .range_raw(&store, None, None, Order::Ascending) .collect(); assert_eq!( @@ -987,7 +983,7 @@ mod test { // Or ranges between two items (even reverse) let all: StdResult> = ALLOWANCE - .prefix_de(b"owner") + .prefix(b"owner") .range_raw( &store, Some(Bound::Exclusive(b"spender1".to_vec())), @@ -1017,7 +1013,7 @@ mod test { // typical range under one prefix as a control let fives = AGES - .prefix_de(5) + .prefix(5) .range_raw(&store, None, None, Order::Ascending) .collect::>>() .unwrap(); @@ -1103,7 +1099,7 @@ mod test { // typical range under one prefix as a control let fives = AGES - .prefix_de(5) + .prefix(5) .range(&store, None, None, Order::Ascending) .collect::>>() .unwrap(); @@ -1113,15 +1109,12 @@ mod test { vec![("789".to_string(), 789), ("987".to_string(), 987)] ); - let keys: Vec<_> = AGES - .no_prefix_de() - .keys(&store, None, None, Order::Ascending) - .collect(); + let keys: Vec<_> = AGES.keys(&store, None, None, Order::Ascending).collect(); println!("keys: {:?}", keys); // using inclusive bounds both sides let include = AGES - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive(3u32)), Some(PrefixBound::inclusive(7u32)), @@ -1135,7 +1128,7 @@ mod test { // using exclusive bounds both sides let exclude = AGES - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::exclusive(3u32)), Some(PrefixBound::exclusive(7u32)), @@ -1149,7 +1142,7 @@ mod test { // using inclusive in descending let include = AGES - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive(3u32)), Some(PrefixBound::inclusive(5u32)), @@ -1163,7 +1156,7 @@ mod test { // using exclusive in descending let include = AGES - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::exclusive(2u32)), Some(PrefixBound::exclusive(5u32)), diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index cdf3abc71..c20fe2e8d 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -87,7 +87,7 @@ where let start = Bound::inclusive(height); let first = self .changelog - .prefix_de(k.clone()) + .prefix(k.clone()) .range_raw(store, Some(start), None, Order::Ascending) .next() .transpose()?; @@ -146,7 +146,7 @@ where let start = Bound::inclusive_int(height); let first = self .changelog - .prefix_de(key) + .prefix(key) .range_raw(store, Some(start), None, Order::Ascending) .next(); From fb36916c17be2728839e6c5e3092ed5543a36f04 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:23:53 +0100 Subject: [PATCH 024/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in SnapshotMap --- packages/storage-plus/src/snapshot/map.rs | 30 +++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 8f50acaf6..a7a3b03c0 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -197,13 +197,13 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a> + KeyDeserialize, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -221,7 +221,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -235,7 +235,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, @@ -249,11 +249,11 @@ where self.no_prefix_de().keys(store, min, max, order) } - pub fn prefix_de(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.primary.namespace(), &p.prefix()) } - pub fn sub_prefix_de(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.primary.namespace(), &p.prefix()) } @@ -467,16 +467,14 @@ mod tests { init_data(&EVERY, &mut store); // let's try to iterate! - let all: StdResult> = EVERY - .range_de(&store, None, None, Order::Ascending) - .collect(); + let all: StdResult> = EVERY.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!(2, all.len()); assert_eq!(all, vec![("C".into(), 13), ("D".into(), 22)]); // let's try to iterate over a range let all: StdResult> = EVERY - .range_de( + .range( &store, Some(Bound::Inclusive(b"C".to_vec())), None, @@ -489,7 +487,7 @@ mod tests { // let's try to iterate over a more restrictive range let all: StdResult> = EVERY - .range_de( + .range( &store, Some(Bound::Inclusive(b"D".to_vec())), None, @@ -511,7 +509,7 @@ mod tests { // let's try to iterate! let all: StdResult> = EVERY_COMPOSITE_KEY - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); assert_eq!(2, all.len()); @@ -534,7 +532,7 @@ mod tests { // let's prefix-range and iterate let all: StdResult> = EVERY_COMPOSITE_KEY - .prefix_range_de( + .prefix_range( &store, None, Some(PrefixBound::exclusive("C")), @@ -556,7 +554,7 @@ mod tests { // let's prefix and iterate let all: StdResult> = EVERY_COMPOSITE_KEY - .prefix_de("C") + .prefix("C") .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -576,7 +574,7 @@ mod tests { // This is similar to calling range() directly, but added here for completeness / // sub_prefix_de type checks let all: StdResult> = EVERY_COMPOSITE_KEY - .sub_prefix_de(()) + .sub_prefix(()) .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); From 32c0aae45ff7eafbf90eacbfaf4a176f91471e9a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:34:09 +0100 Subject: [PATCH 025/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in IndexedMap --- packages/storage-plus/src/indexed_map.rs | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 89d0388c0..b3b9f0b39 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -204,11 +204,11 @@ where K: PrimaryKey<'a>, I: IndexList, { - pub fn sub_prefix_de(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } - pub fn prefix_de(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } } @@ -220,13 +220,13 @@ where K: PrimaryKey<'a> + KeyDeserialize, I: IndexList, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -244,7 +244,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -258,7 +258,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, @@ -994,7 +994,7 @@ mod test { let (pks, datas) = save_data(&mut store, &map); // let's try to iterate! - let all: StdResult> = map.range_de(&store, None, None, Order::Ascending).collect(); + let all: StdResult> = map.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!( all, @@ -1007,7 +1007,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = map - .range_de( + .range( &store, Some(Bound::Inclusive(b"3".to_vec())), None, @@ -1040,7 +1040,7 @@ mod test { // This is similar to calling range() directly, but added here for completeness / prefix_de // type checks let all: StdResult> = map - .prefix_de(()) + .prefix(()) .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -1099,7 +1099,7 @@ mod test { // let's prefix and iterate let result: StdResult> = map - .prefix_de("2") + .prefix("2") .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); @@ -1154,7 +1154,7 @@ mod test { // let's prefix and iterate let result: StdResult> = map - .prefix_de(("1", "2")) + .prefix(("1", "2")) .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); @@ -1206,7 +1206,7 @@ mod test { // let's sub-prefix and iterate let result: StdResult> = map - .sub_prefix_de("1") + .sub_prefix("1") .range(&store, None, None, Order::Ascending) .collect(); let result = result.unwrap(); @@ -1264,7 +1264,7 @@ mod test { // let's try to iterate! let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive("2")), None, @@ -1283,7 +1283,7 @@ mod test { // let's try to iterate over a range let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive("2")), Some(PrefixBound::exclusive("3")), @@ -1345,7 +1345,7 @@ mod test { // let's prefix-range and iterate let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive(("1", "2"))), None, @@ -1373,7 +1373,7 @@ mod test { // let's prefix-range over inclusive bounds on both sides let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive(("1", "2"))), Some(PrefixBound::inclusive(("2", "1"))), From 4db106febf3f1e053755c25343d77160dc9915dd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:40:27 +0100 Subject: [PATCH 026/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in IndexedSnapshotMap --- packages/storage-plus/src/indexed_snapshot.rs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 415cac5cd..d9aae62ca 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -220,11 +220,11 @@ where K: PrimaryKey<'a>, I: IndexList, { - pub fn sub_prefix_de(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } - pub fn prefix_de(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } } @@ -236,13 +236,13 @@ where K: PrimaryKey<'a> + KeyDeserialize, I: IndexList, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -260,7 +260,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -274,7 +274,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, @@ -982,7 +982,7 @@ mod test { let (pks, datas) = save_data(&mut store, &map); // let's try to iterate! - let all: StdResult> = map.range_de(&store, None, None, Order::Ascending).collect(); + let all: StdResult> = map.range(&store, None, None, Order::Ascending).collect(); let all = all.unwrap(); assert_eq!( all, @@ -995,7 +995,7 @@ mod test { // let's try to iterate over a range let all: StdResult> = map - .range_de( + .range( &store, Some(Bound::Inclusive(b"3".to_vec())), None, @@ -1028,7 +1028,7 @@ mod test { // This is similar to calling range() directly, but added here for completeness / prefix_de // type checks let all: StdResult> = map - .prefix_de(()) + .prefix(()) .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -1055,7 +1055,7 @@ mod test { // This is similar to calling range() directly, but added here for completeness / sub_prefix_de // type checks let all: StdResult> = map - .sub_prefix_de(()) + .sub_prefix(()) .range(&store, None, None, Order::Ascending) .collect(); let all = all.unwrap(); @@ -1115,7 +1115,7 @@ mod test { // let's try to iterate! let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive("2")), None, @@ -1134,7 +1134,7 @@ mod test { // let's try to iterate over a range let result: StdResult> = map - .prefix_range_de( + .prefix_range( &store, Some(PrefixBound::inclusive("2")), Some(PrefixBound::exclusive("3")), From d835665429b206f7fcb2df26f5fa4405a96d6298 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:43:17 +0100 Subject: [PATCH 027/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in UniqueIndex --- packages/storage-plus/src/indexed_map.rs | 6 +++--- packages/storage-plus/src/indexed_snapshot.rs | 6 +++--- packages/storage-plus/src/indexes/unique.rs | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index b3b9f0b39..49f6afb2d 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -904,7 +904,7 @@ mod test { let res: StdResult> = map .idx .age - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let ages = res.unwrap(); @@ -937,7 +937,7 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); @@ -966,7 +966,7 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index d9aae62ca..4ac7e0d00 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -894,7 +894,7 @@ mod test { let res: StdResult> = map .idx .age - .range_de(&store, None, None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); let ages = res.unwrap(); @@ -925,7 +925,7 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); @@ -954,7 +954,7 @@ mod test { let res: StdResult> = map .idx .name_lastname - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range(&store, None, None, Order::Ascending) .collect(); let marias = res.unwrap(); diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 38adff44a..7796f9d1f 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -171,13 +171,13 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a>, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -196,7 +196,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -210,7 +210,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, @@ -224,7 +224,7 @@ where self.no_prefix_de().keys(store, min, max, order) } - pub fn prefix_de(&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_de(&self, p: IK::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), From 72a2f4a492558a47226634f8523d14cc5ac22381 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:45:33 +0100 Subject: [PATCH 028/631] Rename prefix_/prefix_range_/keys_/range_de to prefix/prefix_range/keys/range in MultiIndex --- packages/storage-plus/src/indexed_map.rs | 20 +++++++++---------- packages/storage-plus/src/indexed_snapshot.rs | 20 +++++++++---------- packages/storage-plus/src/indexes/multi.rs | 20 +++++++++---------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 49f6afb2d..afa08da9f 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -414,7 +414,7 @@ mod test { let count = map .idx .name - .prefix_de("Maria".to_string()) + .prefix("Maria".to_string()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(2, count); @@ -423,7 +423,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de("Maria".to_string()) + .prefix("Maria".to_string()) .range_raw(&store, None, None, Order::Ascending) .collect::>() .unwrap(); @@ -436,7 +436,7 @@ mod test { let count = map .idx .name - .prefix_de("Marib".to_string()) + .prefix("Marib".to_string()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -445,7 +445,7 @@ mod test { let count = map .idx .name - .prefix_de("Mari`".to_string()) + .prefix("Mari`".to_string()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -454,7 +454,7 @@ mod test { let count = map .idx .name - .prefix_de("Maria5".to_string()) + .prefix("Maria5".to_string()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -560,7 +560,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de("Maria".to_string()) + .prefix("Maria".to_string()) .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -616,7 +616,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de("Maria".to_string()) + .prefix("Maria".to_string()) .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -676,7 +676,7 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix_de(b"Maria".to_vec()) + .sub_prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -737,7 +737,7 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix_de(b"Maria".to_vec()) + .sub_prefix(b"Maria".to_vec()) .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -827,7 +827,7 @@ mod test { -> usize { map.idx .name - .prefix_de(name.to_string()) + .prefix(name.to_string()) .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 4ac7e0d00..955874880 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -430,7 +430,7 @@ mod test { let count = map .idx .name - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(2, count); @@ -439,7 +439,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Ascending) .collect::>() .unwrap(); @@ -452,7 +452,7 @@ mod test { let count = map .idx .name - .prefix_de(b"Marib".to_vec()) + .prefix(b"Marib".to_vec()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -461,7 +461,7 @@ mod test { let count = map .idx .name - .prefix_de(b"Mari`".to_vec()) + .prefix(b"Mari`".to_vec()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -470,7 +470,7 @@ mod test { let count = map .idx .name - .prefix_de(b"Maria5".to_vec()) + .prefix(b"Maria5".to_vec()) .range_raw(&store, None, None, Order::Ascending) .count(); assert_eq!(0, count); @@ -532,7 +532,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -592,7 +592,7 @@ mod test { let marias: Vec<_> = map .idx .name - .prefix_de(b"Maria".to_vec()) + .prefix(b"Maria".to_vec()) .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -657,7 +657,7 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix_de(b"Maria".to_vec()) + .sub_prefix(b"Maria".to_vec()) .range_raw(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -723,7 +723,7 @@ mod test { let marias: Vec<_> = map .idx .name_age - .sub_prefix_de(b"Maria".to_vec()) + .sub_prefix(b"Maria".to_vec()) .range(&store, None, None, Order::Descending) .collect::>() .unwrap(); @@ -818,7 +818,7 @@ mod test { -> usize { map.idx .name - .prefix_de(name.as_bytes().to_vec()) + .prefix(name.as_bytes().to_vec()) .keys_raw(store, None, None, Order::Ascending) .count() }; diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 99f46eaae..b9915e2b0 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -166,13 +166,13 @@ where #[cfg(test)] pub fn count(&self, store: &dyn Storage, p: IK) -> usize { - let prefix = self.prefix_de(p); + let prefix = self.prefix(p); prefix.keys_raw(store, None, None, Order::Ascending).count() } #[cfg(test)] pub fn all_pks(&self, store: &dyn Storage, p: IK) -> Vec> { - let prefix = self.prefix_de(p); + let prefix = self.prefix(p); prefix .keys_raw(store, None, None, Order::Ascending) .collect::>>() @@ -180,7 +180,7 @@ where #[cfg(test)] pub fn all_items(&self, store: &dyn Storage, p: IK) -> StdResult>> { - let prefix = self.prefix_de(p); + let prefix = self.prefix(p); prefix .range_raw(store, None, None, Order::Ascending) .collect() @@ -248,7 +248,7 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - pub fn prefix_de(&self, p: IK) -> Prefix { + pub fn prefix(&self, p: IK) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), @@ -258,7 +258,7 @@ where ) } - pub fn sub_prefix_de(&self, p: IK::Prefix) -> Prefix { + pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), @@ -276,13 +276,13 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + KeyDeserialize + Prefixer<'a>, { - /// While `range_de` over a `prefix_de` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_de` accepts bounds for the lowest and highest elements of the + /// While `range` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. - pub fn prefix_range_de<'c>( + pub fn prefix_range<'c>( &self, store: &'c dyn Storage, min: Option>, @@ -301,7 +301,7 @@ where Box::new(mapped) } - pub fn range_de<'c>( + pub fn range<'c>( &self, store: &'c dyn Storage, min: Option, @@ -315,7 +315,7 @@ where self.no_prefix_de().range(store, min, max, order) } - pub fn keys_de<'c>( + pub fn keys<'c>( &self, store: &'c dyn Storage, min: Option, From b2f46bc7d641b27c104aa71e63e131f1db9836dd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:52:25 +0100 Subject: [PATCH 029/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in Map for consistency --- packages/storage-plus/src/map.rs | 12 ++++++------ packages/storage-plus/src/snapshot/map.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 602a1dc59..c7f7fc02c 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -50,7 +50,7 @@ where } #[cfg(feature = "iterator")] - pub(crate) fn no_prefix(&self) -> Prefix, T> { + pub(crate) fn no_prefix_raw(&self) -> Prefix, T> { Prefix::new(self.namespace, &[]) } @@ -164,7 +164,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -177,7 +177,7 @@ where where T: 'c, { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } } @@ -222,7 +222,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -236,10 +236,10 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.namespace, &[]) } } diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index a7a3b03c0..5d190be49 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -70,7 +70,7 @@ where } fn no_prefix(&self) -> Prefix, T> { - self.primary.no_prefix() + self.primary.no_prefix_raw() } /// load old value and store changelog From 7d7f42506b7707349dad11b9f194fb3ae6faa22a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:54:44 +0100 Subject: [PATCH 030/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in IndexedMap for consistency --- packages/storage-plus/src/indexed_map.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index afa08da9f..b67dadb9a 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -130,7 +130,7 @@ where } // use no_prefix to scan -> range - fn no_prefix(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T> { Prefix::new(self.pk_namespace, &[]) } } @@ -154,7 +154,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -164,7 +164,7 @@ where max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } } @@ -255,7 +255,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -269,10 +269,10 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.pk_namespace, &[]) } } From 1f1a87a6a1f9592ab455362c1291795ae19eab3a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:56:13 +0100 Subject: [PATCH 031/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in SnapshotMap for consistency --- packages/storage-plus/src/snapshot/map.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 5d190be49..030e08937 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -69,7 +69,7 @@ where self.primary.key(k) } - fn no_prefix(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T> { self.primary.no_prefix_raw() } @@ -174,7 +174,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -187,7 +187,7 @@ where where T: 'c, { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } } @@ -232,7 +232,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -246,7 +246,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } pub fn prefix(&self, p: K::Prefix) -> Prefix { @@ -257,7 +257,7 @@ where Prefix::new(self.primary.namespace(), &p.prefix()) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.primary.namespace(), &[]) } } From 42d5db965f6792d16306d174203d268687fac0cc Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:57:57 +0100 Subject: [PATCH 032/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in IndexedSnapshotMap for consistency --- packages/storage-plus/src/indexed_snapshot.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 955874880..2b7914186 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -175,7 +175,7 @@ where } // use no_prefix to scan -> range - pub fn no_prefix(&self) -> Prefix, T> { + pub fn no_prefix_raw(&self) -> Prefix, T> { Prefix::new(self.pk_namespace, &[]) } } @@ -199,7 +199,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -209,7 +209,7 @@ where max: Option, order: cosmwasm_std::Order, ) -> Box> + 'c> { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } } @@ -271,7 +271,7 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -285,10 +285,10 @@ where T: 'c, K::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::new(self.pk_namespace, &[]) } } From b37f1eb191b08257b55699481d17670bf044f082 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 18:59:49 +0100 Subject: [PATCH 033/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in UniqueIndex for consistency --- packages/storage-plus/src/indexes/unique.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 7796f9d1f..06c266fa1 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -112,7 +112,7 @@ where k.joined_key() } - fn no_prefix(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, &[], @@ -150,7 +150,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -160,7 +160,7 @@ where max: Option, order: Order, ) -> Box> + 'c> { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } } @@ -207,7 +207,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -221,7 +221,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } pub fn prefix(&self, p: IK::Prefix) -> Prefix { @@ -244,7 +244,7 @@ where ) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &[], From e7aabeac0ee8635cf7f94edeabad149f0331b380 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 19:00:50 +0100 Subject: [PATCH 034/631] Rename no_prefix to no_prefix_raw, no_prefix_de to no_prefix in MultiIndex for consistency --- packages/storage-plus/src/indexes/multi.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index b9915e2b0..499e7bb44 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(&self) -> Prefix, T> { + fn no_prefix_raw(&self) -> Prefix, T> { Prefix::with_deserialization_functions( self.idx_namespace, &[], @@ -205,7 +205,7 @@ where where T: 'c, { - self.no_prefix().range_raw(store, min, max, order) + self.no_prefix_raw().range_raw(store, min, max, order) } pub fn keys_raw<'c>( @@ -215,7 +215,7 @@ where max: Option, order: Order, ) -> Box> + 'c> { - self.no_prefix().keys_raw(store, min, max, order) + self.no_prefix_raw().keys_raw(store, min, max, order) } /// While `range` over a `prefix` fixes the prefix to one element and iterates over the @@ -312,7 +312,7 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().range(store, min, max, order) + self.no_prefix().range(store, min, max, order) } pub fn keys<'c>( @@ -326,10 +326,10 @@ where T: 'c, PK::Output: 'static, { - self.no_prefix_de().keys(store, min, max, order) + self.no_prefix().keys(store, min, max, order) } - fn no_prefix_de(&self) -> Prefix { + fn no_prefix(&self) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &[], From ed513e629cd6cdbf610e1cd8e0184df1b48da32c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 20:30:14 +0100 Subject: [PATCH 035/631] Replace range_raw() plus manual deserialization by keys() --- packages/utils/src/pagination.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/utils/src/pagination.rs b/packages/utils/src/pagination.rs index b346fb776..7af917acd 100644 --- a/packages/utils/src/pagination.rs +++ b/packages/utils/src/pagination.rs @@ -36,7 +36,7 @@ pub fn calc_range_start_string(start_after: Option) -> Option> { #[cfg(test)] mod test { use super::*; - use cosmwasm_std::{testing::mock_dependencies, Order, StdError}; + use cosmwasm_std::{testing::mock_dependencies, Order}; use cw_storage_plus::{Bound, Map}; pub const HOLDERS: Map<&Addr, usize> = Map::new("some_data"); @@ -46,12 +46,6 @@ mod test { Addr::unchecked(format!("addr{:0>8}", i)) } - fn deser_holder_kv(holder_kv: Result<(Vec, usize), StdError>) -> (String, usize) { - let (k_bytes, v) = holder_kv.unwrap(); - let key = std::str::from_utf8(&k_bytes).unwrap().to_string(); - (key, v) - } - #[test] fn calc_range_start_works_as_expected() { let total_elements_count = 100; @@ -72,15 +66,15 @@ mod test { let start = calc_range_start(start_after).map(Bound::exclusive); - let holders: Vec<(String, usize)> = HOLDERS - .range_raw(&deps.storage, start, None, Order::Ascending) - .map(deser_holder_kv) + let holders = HOLDERS + .keys(&deps.storage, start, None, Order::Ascending) .take(LIMIT) - .collect(); + .collect::>>() + .unwrap(); for (i, holder) in holders.into_iter().enumerate() { let global_index = j * LIMIT + i; - assert_eq!(holder.0, addr_from_i(global_index)); + assert_eq!(holder, addr_from_i(global_index)); } } } @@ -101,15 +95,15 @@ mod test { let end = calc_range_end(end_before).map(Bound::exclusive); - let holders: Vec<(String, usize)> = HOLDERS - .range_raw(&deps.storage, None, end, Order::Descending) - .map(deser_holder_kv) + let holders = HOLDERS + .keys(&deps.storage, None, end, Order::Descending) .take(LIMIT) - .collect(); + .collect::>>() + .unwrap(); for (i, holder) in holders.into_iter().enumerate() { let global_index = total_elements_count - i - j * LIMIT - 1; - assert_eq!(holder.0, addr_from_i(global_index)); + assert_eq!(holder, addr_from_i(global_index)); } } } From 8f00fb31f749775ab6a677b30c76ea2285acd18e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 20:53:24 +0100 Subject: [PATCH 036/631] Replace range_raw() plus manual deserialization by range() --- contracts/cw1155-base/src/contract.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 74291b0f1..b83ca5d41 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -1,7 +1,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Record, Response, StdResult, - SubMsg, Uint128, + to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, SubMsg, + Uint128, }; use cw_storage_plus::Bound; @@ -478,10 +478,10 @@ pub fn query(deps: Deps, env: Env, msg: Cw1155QueryMsg) -> StdResult { } } -fn parse_approval(item: StdResult>) -> StdResult { - item.and_then(|(k, expires)| { - let spender = String::from_utf8(k)?; - Ok(cw1155::Approval { spender, expires }) +fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult { + item.map(|(addr, expires)| cw1155::Approval { + spender: addr.into(), + expires, }) } @@ -498,10 +498,10 @@ fn query_all_approvals( let operators = APPROVES .prefix(&owner) - .range_raw(deps.storage, start, None, Order::Ascending) + .range(deps.storage, start, None, Order::Ascending) .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) .take(limit) - .map(parse_approval) + .map(build_approval) .collect::>()?; Ok(ApprovedForAllResponse { operators }) } From 64f3a33f020170cede0ded3ddebbd34a3da7e2b1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 20:53:58 +0100 Subject: [PATCH 037/631] Replace range_raw() plus manual deserialization by keys() --- contracts/cw1155-base/src/contract.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index b83ca5d41..e3195cff3 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -517,9 +517,8 @@ fn query_tokens( let tokens = BALANCES .prefix(&owner) - .range_raw(deps.storage, start, None, Order::Ascending) + .keys(deps.storage, start, None, Order::Ascending) .take(limit) - .map(|item| item.map(|(k, _)| String::from_utf8(k).unwrap())) .collect::>()?; Ok(TokensResponse { tokens }) } @@ -532,9 +531,8 @@ fn query_all_tokens( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); let tokens = TOKENS - .range_raw(deps.storage, start, None, Order::Ascending) + .keys(deps.storage, start, None, Order::Ascending) .take(limit) - .map(|item| item.map(|(k, _)| String::from_utf8(k).unwrap())) .collect::>()?; Ok(TokensResponse { tokens }) } From 3b4ba152bce41ba47ff4554d73fcded40a7f17ac Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 21:22:49 +0100 Subject: [PATCH 038/631] Replace range_raw() + deserialization by range() --- contracts/cw1-subkeys/src/contract.rs | 34 ++++++++++++--------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index 84304be68..fca7ee1a4 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -409,8 +409,8 @@ pub fn query_all_allowances( // we use raw addresses here.... let start = start_after.map(Bound::exclusive); - let res: StdResult> = ALLOWANCES - .range_raw(deps.storage, start, None, Order::Ascending) + let allowances = ALLOWANCES + .range(deps.storage, start, None, Order::Ascending) .filter(|item| { if let Ok((_, allow)) = item { !allow.expires.is_expired(&env.block) @@ -420,16 +420,14 @@ pub fn query_all_allowances( }) .take(limit) .map(|item| { - item.and_then(|(k, allow)| { - Ok(AllowanceInfo { - spender: String::from_utf8(k)?, - balance: allow.balance, - expires: allow.expires, - }) + item.map(|(addr, allow)| AllowanceInfo { + spender: addr.into(), + balance: allow.balance, + expires: allow.expires, }) }) - .collect(); - Ok(AllAllowancesResponse { allowances: res? }) + .collect::>>()?; + Ok(AllAllowancesResponse { allowances }) } // return a list of all permissions here @@ -441,19 +439,17 @@ pub fn query_all_permissions( let limit = calc_limit(limit); let start = start_after.map(Bound::exclusive); - let res: StdResult> = PERMISSIONS - .range_raw(deps.storage, start, None, Order::Ascending) + let permissions = PERMISSIONS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - item.and_then(|(k, perm)| { - Ok(PermissionsInfo { - spender: String::from_utf8(k)?, - permissions: perm, - }) + item.map(|(addr, perm)| PermissionsInfo { + spender: addr.into(), + permissions: perm, }) }) - .collect(); - Ok(AllPermissionsResponse { permissions: res? }) + .collect::>>()?; + Ok(AllPermissionsResponse { permissions }) } // Migrate contract if version is lower than current version From d0d7c598fe460decd1aa1fd3d7c1f7299c80e0fc Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 21:33:41 +0100 Subject: [PATCH 039/631] Replace keys_raw() + deserialization by keys() --- contracts/cw20-atomic-swap/src/state.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/cw20-atomic-swap/src/state.rs b/contracts/cw20-atomic-swap/src/state.rs index 7df449e9d..0a1202630 100644 --- a/contracts/cw20-atomic-swap/src/state.rs +++ b/contracts/cw20-atomic-swap/src/state.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, Binary, BlockInfo, Order, StdError, StdResult, Storage}; +use cosmwasm_std::{Addr, Binary, BlockInfo, Order, StdResult, Storage}; use cw_storage_plus::{Bound, Map}; use cw20::{Balance, Expiration}; @@ -32,9 +32,8 @@ pub fn all_swap_ids( limit: usize, ) -> StdResult> { SWAPS - .keys_raw(storage, start, None, Order::Ascending) + .keys(storage, start, None, Order::Ascending) .take(limit) - .map(|k| String::from_utf8(k).map_err(|_| StdError::invalid_utf8("Parsing swap id"))) .collect() } From 3c78f51601c1e89559f3de239a4cc10026ff7644 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 21:46:18 +0100 Subject: [PATCH 040/631] Replace range_raw() + deserialization by range() --- contracts/cw20-base/src/enumerable.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 7b6c526c8..d93903536 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -18,22 +18,19 @@ pub fn query_all_allowances( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); - let allowances: StdResult> = ALLOWANCES + let allowances = ALLOWANCES .prefix(&owner_addr) - .range_raw(deps.storage, start, None, Order::Ascending) + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (k, v) = item?; - Ok(AllowanceInfo { - spender: String::from_utf8(k)?, - allowance: v.allowance, - expires: v.expires, + item.map(|(addr, allow)| AllowanceInfo { + spender: addr.into(), + allowance: allow.allowance, + expires: allow.expires, }) }) - .collect(); - Ok(AllAllowancesResponse { - allowances: allowances?, - }) + .collect::>()?; + Ok(AllAllowancesResponse { allowances }) } pub fn query_all_accounts( From c5eba5bf0464a338764bc1454a5da57c23807b13 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 21:47:38 +0100 Subject: [PATCH 041/631] Replace keys_raw() + deserialization by keys() --- contracts/cw20-base/src/enumerable.rs | 12 +++++------- contracts/cw20-escrow/src/state.rs | 5 ++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index d93903536..cb7dc74fc 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -41,15 +41,13 @@ pub fn query_all_accounts( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); - let accounts: Result, _> = BALANCES - .keys_raw(deps.storage, start, None, Order::Ascending) - .map(String::from_utf8) + let accounts = BALANCES + .keys(deps.storage, start, None, Order::Ascending) .take(limit) - .collect(); + .map(|item| item.map(Into::into)) + .collect::>()?; - Ok(AllAccountsResponse { - accounts: accounts?, - }) + Ok(AllAccountsResponse { accounts }) } #[cfg(test)] diff --git a/contracts/cw20-escrow/src/state.rs b/contracts/cw20-escrow/src/state.rs index c09dcd3e2..3940d6160 100644 --- a/contracts/cw20-escrow/src/state.rs +++ b/contracts/cw20-escrow/src/state.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, Coin, Env, Order, StdError, StdResult, Storage, Timestamp}; +use cosmwasm_std::{Addr, Coin, Env, Order, StdResult, Storage, Timestamp}; use cw_storage_plus::Map; use cw20::{Balance, Cw20CoinVerified}; @@ -95,8 +95,7 @@ pub const ESCROWS: Map<&str, Escrow> = Map::new("escrow"); /// This returns the list of ids for all registered escrows pub fn all_escrow_ids(storage: &dyn Storage) -> StdResult> { ESCROWS - .keys_raw(storage, None, None, Order::Ascending) - .map(|k| String::from_utf8(k).map_err(|_| StdError::invalid_utf8("parsing escrow key"))) + .keys(storage, None, None, Order::Ascending) .collect() } From 5f9da6bf5faa190d2c9311c98e37899713fdede9 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 22:04:17 +0100 Subject: [PATCH 042/631] Replace range_raw() + deserialization by range() Refactor raw_range iterator --- contracts/cw20-ics20/src/contract.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 03a806102..132c08dd6 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -151,32 +151,30 @@ fn query_port(deps: Deps) -> StdResult { } fn query_list(deps: Deps) -> StdResult { - let channels: StdResult> = CHANNEL_INFO + let channels = CHANNEL_INFO .range_raw(deps.storage, None, None, Order::Ascending) .map(|r| r.map(|(_, v)| v)) - .collect(); - Ok(ListChannelsResponse { - channels: channels?, - }) + .collect::>()?; + Ok(ListChannelsResponse { channels }) } // make public for ibc tests pub fn query_channel(deps: Deps, id: String) -> StdResult { let info = CHANNEL_INFO.load(deps.storage, &id)?; // this returns Vec<(outstanding, total)> - let state: StdResult> = CHANNEL_STATE + let state = CHANNEL_STATE .prefix(&id) - .range_raw(deps.storage, None, None, Order::Ascending) + .range(deps.storage, None, None, Order::Ascending) .map(|r| { - let (k, v) = r?; - let denom = String::from_utf8(k)?; - let outstanding = Amount::from_parts(denom.clone(), v.outstanding); - let total = Amount::from_parts(denom, v.total_sent); - Ok((outstanding, total)) + r.map(|(denom, v)| { + let outstanding = Amount::from_parts(denom.clone(), v.outstanding); + let total = Amount::from_parts(denom, v.total_sent); + (outstanding, total) + }) }) - .collect(); + .collect::>>()?; // we want (Vec, Vec) - let (balances, total_sent) = state?.into_iter().unzip(); + let (balances, total_sent) = state.into_iter().unzip(); Ok(ChannelResponse { info, From f04f1f3b519a6774cddcf6fb88f2183ccb4992e9 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 Dec 2021 22:56:59 +0100 Subject: [PATCH 043/631] Replace range_raw() + deserialization by range() --- contracts/cw3-fixed-multisig/src/contract.rs | 69 ++++++++++---------- contracts/cw3-flex-multisig/src/contract.rs | 52 +++++++-------- contracts/cw4-group/src/contract.rs | 13 ++-- contracts/cw4-stake/src/contract.rs | 13 ++-- 4 files changed, 70 insertions(+), 77 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 48a600834..2f2ef70d5 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -17,9 +17,7 @@ use utils::Expiration; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{ - next_id, parse_id, Ballot, Config, Proposal, BALLOTS, CONFIG, PROPOSALS, VOTERS, -}; +use crate::state::{next_id, Ballot, Config, Proposal, BALLOTS, CONFIG, PROPOSALS, VOTERS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-fixed-multisig"; @@ -315,13 +313,13 @@ fn list_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive_int); - let props: StdResult> = PROPOSALS - .range_raw(deps.storage, start, None, Order::Ascending) + let proposals = PROPOSALS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|p| map_proposal(&env.block, &threshold, p)) - .collect(); + .collect::>()?; - Ok(ProposalListResponse { proposals: props? }) + Ok(ProposalListResponse { proposals }) } fn reverse_proposals( @@ -338,30 +336,31 @@ fn reverse_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let end = start_before.map(Bound::exclusive_int); - let props: StdResult> = PROPOSALS - .range_raw(deps.storage, None, end, Order::Descending) + let proposals = PROPOSALS + .range(deps.storage, None, end, Order::Descending) .take(limit) .map(|p| map_proposal(&env.block, &threshold, p)) - .collect(); + .collect::>()?; - Ok(ProposalListResponse { proposals: props? }) + Ok(ProposalListResponse { proposals }) } fn map_proposal( block: &BlockInfo, threshold: &ThresholdResponse, - item: StdResult<(Vec, Proposal)>, + item: StdResult<(u64, Proposal)>, ) -> StdResult { - let (key, prop) = item?; - let status = prop.current_status(block); - Ok(ProposalResponse { - id: parse_id(&key)?, - title: prop.title, - description: prop.description, - msgs: prop.msgs, - status, - expires: prop.expires, - threshold: threshold.clone(), + item.map(|(id, prop)| { + let status = prop.current_status(block); + ProposalResponse { + id, + title: prop.title, + description: prop.description, + msgs: prop.msgs, + status, + expires: prop.expires, + threshold: threshold.clone(), + } }) } @@ -385,21 +384,20 @@ fn list_votes( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); - let votes: StdResult> = BALLOTS + let votes = BALLOTS .prefix(proposal_id) - .range_raw(deps.storage, start, None, Order::Ascending) + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (key, ballot) = item?; - Ok(VoteInfo { - voter: String::from_utf8(key)?, + item.map(|(addr, ballot)| VoteInfo { + voter: addr.into(), vote: ballot.vote, weight: ballot.weight, }) }) - .collect(); + .collect::>()?; - Ok(VoteListResponse { votes: votes? }) + Ok(VoteListResponse { votes }) } fn query_voter(deps: Deps, voter: String) -> StdResult { @@ -416,19 +414,18 @@ fn list_voters( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive); - let voters: StdResult> = VOTERS - .range_raw(deps.storage, start, None, Order::Ascending) + let voters = VOTERS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (key, weight) = item?; - Ok(VoterDetail { - addr: String::from_utf8(key)?, + item.map(|(addr, weight)| VoterDetail { + addr: addr.into(), weight, }) }) - .collect(); + .collect::>()?; - Ok(VoterListResponse { voters: voters? }) + Ok(VoterListResponse { voters }) } #[cfg(test)] diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index c7293d99c..38169b6b5 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -18,9 +18,7 @@ use utils::{maybe_addr, Expiration}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{ - next_id, parse_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS, -}; +use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; @@ -317,13 +315,13 @@ fn list_proposals( ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive_int); - let props: StdResult> = PROPOSALS - .range_raw(deps.storage, start, None, Order::Ascending) + let proposals = PROPOSALS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|p| map_proposal(&env.block, p)) - .collect(); + .collect::>()?; - Ok(ProposalListResponse { proposals: props? }) + Ok(ProposalListResponse { proposals }) } fn reverse_proposals( @@ -335,7 +333,7 @@ fn reverse_proposals( let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let end = start_before.map(Bound::exclusive_int); let props: StdResult> = PROPOSALS - .range_raw(deps.storage, None, end, Order::Descending) + .range(deps.storage, None, end, Order::Descending) .take(limit) .map(|p| map_proposal(&env.block, p)) .collect(); @@ -345,19 +343,20 @@ fn reverse_proposals( fn map_proposal( block: &BlockInfo, - item: StdResult<(Vec, Proposal)>, + item: StdResult<(u64, Proposal)>, ) -> StdResult { - let (key, prop) = item?; - let status = prop.current_status(block); - let threshold = prop.threshold.to_response(prop.total_weight); - Ok(ProposalResponse { - id: parse_id(&key)?, - title: prop.title, - description: prop.description, - msgs: prop.msgs, - status, - expires: prop.expires, - threshold, + item.map(|(id, prop)| { + let status = prop.current_status(block); + let threshold = prop.threshold.to_response(prop.total_weight); + ProposalResponse { + id, + title: prop.title, + description: prop.description, + msgs: prop.msgs, + status, + expires: prop.expires, + threshold, + } }) } @@ -382,21 +381,20 @@ fn list_votes( let addr = maybe_addr(deps.api, start_after)?; let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); - let votes: StdResult> = BALLOTS + let votes = BALLOTS .prefix(proposal_id) - .range_raw(deps.storage, start, None, Order::Ascending) + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (voter, ballot) = item?; - Ok(VoteInfo { - voter: String::from_utf8(voter)?, + item.map(|(addr, ballot)| VoteInfo { + voter: addr.into(), vote: ballot.vote, weight: ballot.weight, }) }) - .collect(); + .collect::>()?; - Ok(VoteListResponse { votes: votes? }) + Ok(VoteListResponse { votes }) } fn query_voter(deps: Deps, voter: String) -> StdResult { diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index e0a34d3f1..e41e9d9f6 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -192,19 +192,18 @@ fn list_members( let addr = maybe_addr(deps.api, start_after)?; let start = addr.map(|addr| Bound::exclusive(addr.to_string())); - let members: StdResult> = MEMBERS - .range_raw(deps.storage, start, None, Order::Ascending) + let members = MEMBERS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (key, weight) = item?; - Ok(Member { - addr: String::from_utf8(key)?, + item.map(|(addr, weight)| Member { + addr: addr.into(), weight, }) }) - .collect(); + .collect::>()?; - Ok(MemberListResponse { members: members? }) + Ok(MemberListResponse { members }) } #[cfg(test)] diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 20aa3b6f2..635a20080 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -341,19 +341,18 @@ fn list_members( let addr = maybe_addr(deps.api, start_after)?; let start = addr.map(|addr| Bound::exclusive(addr.as_ref())); - let members: StdResult> = MEMBERS - .range_raw(deps.storage, start, None, Order::Ascending) + let members = MEMBERS + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (key, weight) = item?; - Ok(Member { - addr: String::from_utf8(key)?, + item.map(|(addr, weight)| Member { + addr: addr.into(), weight, }) }) - .collect(); + .collect::>()?; - Ok(MemberListResponse { members: members? }) + Ok(MemberListResponse { members }) } #[cfg(test)] From ae2537cf60e5b15321cdeeaaba08f5bbe3425365 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Dec 2021 07:59:20 +0100 Subject: [PATCH 044/631] Update test cases/comments in Map for clarity --- packages/storage-plus/src/map.rs | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index c7f7fc02c..320c7a64c 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -124,7 +124,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) #[cfg(feature = "iterator")] impl<'a, K, T> Map<'a, K, T> where @@ -133,8 +133,8 @@ where // Other cases need to call prefix() first K: PrimaryKey<'a>, { - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the `Prefix` + /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the `Prefix` /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. @@ -395,7 +395,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_simple_key() { + fn range_raw_simple_key() { let mut store = MockStorage::new(); // save and load on two keys @@ -457,7 +457,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_simple_string_key() { + fn range_simple_string_key() { let mut store = MockStorage::new(); // save and load on two keys @@ -517,7 +517,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_simple_integer_key() { + fn range_simple_integer_key() { let mut store = MockStorage::new(); // save and load on two keys @@ -570,7 +570,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_composite_key() { + fn range_raw_composite_key() { let mut store = MockStorage::new(); // save and load on three keys, one under different owner @@ -614,7 +614,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_composite_key() { + fn range_composite_key() { let mut store = MockStorage::new(); // save and load on three keys, one under different owner @@ -643,7 +643,7 @@ mod test { ] ); - // let's try to iterate over a prefix_de + // let's try to iterate over a prefix let all: StdResult> = ALLOWANCE .prefix(b"owner") .range(&store, None, None, Order::Ascending) @@ -658,7 +658,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_triple_key() { + fn range_raw_triple_key() { let mut store = MockStorage::new(); // save and load on three keys, one under different owner @@ -725,7 +725,7 @@ mod test { .collect(); let all = all.unwrap(); assert_eq!(3, all.len()); - // Use range_de() if you want key deserialization + // Use range() if you want key deserialization assert_eq!( all, vec![ @@ -738,7 +738,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_triple_key() { + fn range_triple_key() { let mut store = MockStorage::new(); // save and load on three keys, one under different owner @@ -769,7 +769,7 @@ mod test { ] ); - // let's iterate over a sub_prefix_de + // let's iterate over a sub_prefix let all: StdResult> = TRIPLE .sub_prefix(b"owner") .range(&store, None, None, Order::Ascending) @@ -785,7 +785,7 @@ mod test { ] ); - // let's iterate over a prefix_de + // let's iterate over a prefix let all: StdResult> = TRIPLE .prefix((b"owner", 9)) .range(&store, None, None, Order::Ascending) @@ -931,7 +931,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn readme_with_range() -> StdResult<()> { + fn readme_with_range_raw() -> StdResult<()> { let mut store = MockStorage::new(); // save and load on two keys @@ -998,7 +998,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefixed_range_works() { + fn prefixed_range_raw_works() { // this is designed to look as much like a secondary index as possible // we want to query over a range of u32 for the first key and all subkeys const AGES: Map<(u32, Vec), u64> = Map::new("ages"); @@ -1084,7 +1084,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefixed_range_de_works() { + fn prefixed_range_works() { // this is designed to look as much like a secondary index as possible // we want to query over a range of u32 for the first key and all subkeys const AGES: Map<(u32, &str), u64> = Map::new("ages"); From 8a0365f5f5a6b8c6eb7904e794910280dadade62 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Dec 2021 08:09:52 +0100 Subject: [PATCH 045/631] Update test cases/comments in SnapshotMap --- packages/storage-plus/src/snapshot/map.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index 030e08937..ef1d572b4 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -156,7 +156,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) impl<'a, K, T> SnapshotMap<'a, K, T> where T: Serialize + DeserializeOwned + Clone, @@ -333,7 +333,7 @@ mod tests { const VALUES_START_5: &[(&str, Option)] = &[("A", Some(8)), ("B", None), ("C", Some(13)), ("D", None)]; - // Same as `init_data`, but we have a composite key for testing range_de. + // Same as `init_data`, but we have a composite key for testing range. fn init_data_composite_key(map: &TestMapCompositeKey, storage: &mut dyn Storage) { map.save(storage, ("A", "B"), &5, 1).unwrap(); map.save(storage, ("B", "A"), &7, 2).unwrap(); @@ -460,7 +460,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] - fn range_de_simple_string_key() { + fn range_simple_string_key() { use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -501,7 +501,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] - fn range_de_composite_key() { + fn range_composite_key() { use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -524,7 +524,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] - fn prefix_range_de_composite_key() { + fn prefix_range_composite_key() { use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -546,7 +546,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] - fn prefix_de_composite_key() { + fn prefix_composite_key() { use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -564,7 +564,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] - fn sub_prefix_de_composite_key() { + fn sub_prefix_composite_key() { use cosmwasm_std::Order; let mut store = MockStorage::new(); @@ -572,7 +572,7 @@ mod tests { // Let's sub-prefix and iterate. // This is similar to calling range() directly, but added here for completeness / - // sub_prefix_de type checks + // sub_prefix type checks let all: StdResult> = EVERY_COMPOSITE_KEY .sub_prefix(()) .range(&store, None, None, Order::Ascending) From 200948f89b29f93e7d935202704dc8e7fa53dd8d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Dec 2021 08:11:02 +0100 Subject: [PATCH 046/631] Adjust indexes comments --- packages/storage-plus/src/indexes/multi.rs | 6 +++--- packages/storage-plus/src/indexes/unique.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 499e7bb44..91a4f29c7 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -187,7 +187,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> where T: Serialize + DeserializeOwned + Clone, @@ -218,8 +218,8 @@ where self.no_prefix_raw().keys_raw(store, min, max, order) } - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the + /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on /// `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs index 06c266fa1..6f729db10 100644 --- a/packages/storage-plus/src/indexes/unique.rs +++ b/packages/storage-plus/src/indexes/unique.rs @@ -132,7 +132,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK> where T: Serialize + DeserializeOwned + Clone, From 4181f547282ed3b1cc51ad9b2b3d449b3e81426a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Dec 2021 08:31:25 +0100 Subject: [PATCH 047/631] Update test cases/comments in indexed maps --- packages/storage-plus/src/indexed_map.rs | 42 +++++++++---------- packages/storage-plus/src/indexed_snapshot.rs | 36 ++++++++-------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index b67dadb9a..d9a7df53c 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -135,7 +135,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) impl<'a, K, T, I> IndexedMap<'a, K, T, I> where K: PrimaryKey<'a>, @@ -175,8 +175,8 @@ where T: Serialize + DeserializeOwned + Clone, I: IndexList, { - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the `Prefix` + /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the + /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the `Prefix` /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't /// solve them. @@ -520,7 +520,7 @@ mod test { } #[test] - fn range_simple_key_by_multi_index() { + fn range_raw_simple_key_by_multi_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -576,7 +576,7 @@ mod test { } #[test] - fn range_de_simple_key_by_multi_index() { + fn range_simple_key_by_multi_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -632,7 +632,7 @@ mod test { } #[test] - fn range_composite_key_by_multi_index() { + fn range_raw_composite_key_by_multi_index() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -693,7 +693,7 @@ mod test { } #[test] - fn range_de_composite_key_by_multi_index() { + fn range_composite_key_by_multi_index() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -861,7 +861,7 @@ mod test { } #[test] - fn range_simple_key_by_unique_index() { + fn range_raw_simple_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -894,7 +894,7 @@ mod test { } #[test] - fn range_de_simple_key_by_unique_index() { + fn range_simple_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -927,7 +927,7 @@ mod test { } #[test] - fn range_composite_key_by_unique_index() { + fn range_raw_composite_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -956,7 +956,7 @@ mod test { } #[test] - fn range_de_composite_key_by_unique_index() { + fn range_composite_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_map(); @@ -986,7 +986,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_simple_string_key() { + fn range_simple_string_key() { let mut store = MockStorage::new(); let map = build_map(); @@ -1029,7 +1029,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_de_simple_string_key() { + fn prefix_simple_string_key() { let mut store = MockStorage::new(); let map = build_map(); @@ -1037,7 +1037,7 @@ mod test { let (pks, datas) = save_data(&mut store, &map); // Let's prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / prefix_de + // This is similar to calling range() directly, but added here for completeness / prefix // type checks let all: StdResult> = map .prefix(()) @@ -1056,7 +1056,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_de_composite_key() { + fn prefix_composite_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -1111,7 +1111,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_de_triple_key() { + fn prefix_triple_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -1163,7 +1163,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn sub_prefix_de_triple_key() { + fn sub_prefix_triple_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -1221,7 +1221,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_range_de_simple_key() { + fn prefix_range_simple_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -1262,7 +1262,7 @@ mod test { let pk4 = ("3", "5630"); map.save(&mut store, pk4, &data4).unwrap(); - // let's try to iterate! + // let's prefix-range and iterate let result: StdResult> = map .prefix_range( &store, @@ -1281,7 +1281,7 @@ mod test { ] ); - // let's try to iterate over a range + // let's try to iterate over a more restrictive prefix-range! let result: StdResult> = map .prefix_range( &store, @@ -1302,7 +1302,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_range_de_triple_key() { + fn prefix_range_triple_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 2b7914186..7b2eb7b82 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -180,7 +180,7 @@ where } } -// short-cut for simple keys, rather than .prefix(()).range(...) +// short-cut for simple keys, rather than .prefix(()).range_raw(...) impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> where K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, @@ -488,7 +488,7 @@ mod test { } #[test] - fn range_simple_key_by_multi_index() { + fn range_raw_simple_key_by_multi_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); let mut height = 1; @@ -548,7 +548,7 @@ mod test { } #[test] - fn range_de_simple_key_by_multi_index() { + fn range_simple_key_by_multi_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); let mut height = 1; @@ -608,7 +608,7 @@ mod test { } #[test] - fn range_composite_key_by_multi_index() { + fn range_raw_composite_key_by_multi_index() { let mut store = MockStorage::new(); let mut height = 2; @@ -674,7 +674,7 @@ mod test { } #[test] - fn range_de_composite_key_by_multi_index() { + fn range_composite_key_by_multi_index() { let mut store = MockStorage::new(); let mut height = 2; @@ -853,7 +853,7 @@ mod test { } #[test] - fn range_simple_key_by_unique_index() { + fn range_raw_simple_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -884,7 +884,7 @@ mod test { } #[test] - fn range_de_simple_key_by_unique_index() { + fn range_simple_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -915,7 +915,7 @@ mod test { } #[test] - fn range_composite_key_by_unique_index() { + fn range_raw_composite_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -944,7 +944,7 @@ mod test { } #[test] - fn range_de_composite_key_by_unique_index() { + fn range_composite_key_by_unique_index() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -974,7 +974,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn range_de_simple_string_key() { + fn range_simple_string_key() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -1017,7 +1017,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_de_simple_string_key() { + fn prefix_simple_string_key() { let mut store = MockStorage::new(); let map = build_snapshot_map(); @@ -1025,7 +1025,7 @@ mod test { let (pks, datas) = save_data(&mut store, &map); // Let's prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / prefix_de + // This is similar to calling range() directly, but added here for completeness / prefix // type checks let all: StdResult> = map .prefix(()) @@ -1044,15 +1044,15 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn sub_prefix_de_simple_string_key() { + fn sub_prefix_simple_string_key() { let mut store = MockStorage::new(); let map = build_snapshot_map(); // save data let (pks, datas) = save_data(&mut store, &map); - // Let's prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / sub_prefix_de + // Let's sub-prefix and iterate. + // This is similar to calling range() directly, but added here for completeness / sub_prefix // type checks let all: StdResult> = map .sub_prefix(()) @@ -1071,7 +1071,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn prefix_range_de_simple_key() { + fn prefix_range_simple_key() { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { @@ -1113,7 +1113,7 @@ mod test { let pk4: (&str, &str) = ("3", "5630"); map.save(&mut store, pk4, &data4, 1).unwrap(); - // let's try to iterate! + // let's prefix-range and iterate let result: StdResult> = map .prefix_range( &store, @@ -1132,7 +1132,7 @@ mod test { ] ); - // let's try to iterate over a range + // let's try to iterate over a more restrictive prefix-range! let result: StdResult> = map .prefix_range( &store, From 97d6683c3549386805d4eecd2edddd8dd29d733b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 14 Dec 2021 16:07:01 +0100 Subject: [PATCH 048/631] Add deprecation notices for `IntKey` type aliases --- packages/storage-plus/src/keys.rs | 10 ++++++++++ packages/storage-plus/src/lib.rs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 15b7a6c19..08cb4caf9 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -326,16 +326,26 @@ impl<'a, T: Endian> Prefixer<'a> for IntKey { } } +#[deprecated(note = "It is suggested to use `u8` as key type instead of the `U8Key` wrapper")] pub type U8Key = IntKey; +#[deprecated(note = "It is suggested to use `u16` as key type instead of the `U16Key` wrapper")] pub type U16Key = IntKey; +#[deprecated(note = "It is suggested to use `u32` as key type instead of the `U32Key` wrapper")] pub type U32Key = IntKey; +#[deprecated(note = "It is suggested to use `u64` as key type instead of the `U64Key` wrapper")] pub type U64Key = IntKey; +#[deprecated(note = "Consider using 64-bit keys instead of the `U128Key` wrapper")] pub type U128Key = IntKey; +#[deprecated(note = "It is suggested to use `i8` as key type instead of the `I8Key` wrapper")] pub type I8Key = IntKey; +#[deprecated(note = "It is suggested to use `i16` as key type instead of the `I16Key` wrapper")] pub type I16Key = IntKey; +#[deprecated(note = "It is suggested to use `i32` as key type instead of the `I32Key` wrapper")] pub type I32Key = IntKey; +#[deprecated(note = "It is suggested to use `i64` as key type instead of the `I64Key` wrapper")] pub type I64Key = IntKey; +#[deprecated(note = "Consider using 64-bit keys instead of the `I128Key` wrapper")] pub type I128Key = IntKey; /// It will cast one-particular int type into a Key via Vec, ensuring you don't mix up u32 and u64 diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 53bbba036..0ab72b3a5 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -24,7 +24,11 @@ pub use indexes::UniqueIndex; #[cfg(feature = "iterator")] pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; pub use item::Item; +// TODO: Remove along with `IntKey` +#[allow(deprecated)] pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; +// TODO: Remove along with `IntKey` +#[allow(deprecated)] pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; pub use map::Map; pub use path::Path; From 155909bbabd6700d003001eb2cdb3f108d8ee638 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 14:13:14 +0100 Subject: [PATCH 049/631] Add integer key builder / helpers --- packages/storage-plus/src/int_key.rs | 51 ++++++++++++++++++++++++++++ packages/storage-plus/src/lib.rs | 1 + 2 files changed, 52 insertions(+) create mode 100644 packages/storage-plus/src/int_key.rs diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs new file mode 100644 index 000000000..8462f7d68 --- /dev/null +++ b/packages/storage-plus/src/int_key.rs @@ -0,0 +1,51 @@ +use std::mem; + +/// Our int keys are simply the Big-endian representation bytes for unsigned ints, +/// but "sign-flipped" (xored msb) Big-endian bytes for signed ints. +/// So that the representation of signed integers is correctly ordered lexicographically. +pub trait CwIntKey: Sized + Copy { + type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; + + fn to_cw_bytes(&self) -> Self::Buf; + fn from_cw_bytes(bytes: Self::Buf) -> Self; +} + +macro_rules! cw_uint_keys { + (for $($t:ty),+) => { + $(impl CwIntKey for $t { + type Buf = [u8; mem::size_of::<$t>()]; + + fn to_cw_bytes(&self) -> Self::Buf { + self.to_be_bytes() + } + + fn from_cw_bytes(bytes: Self::Buf) -> Self { + Self::from_be_bytes(bytes) + } + })* + } +} + +cw_uint_keys!(for u8, u16, u32, u64, u128); + +macro_rules! cw_int_keys { + (for $($t:ty),+) => { + $(impl CwIntKey for $t { + type Buf = [u8; mem::size_of::<$t>()]; + + fn to_cw_bytes(&self) -> Self::Buf { + let mut bytes = self.to_be_bytes(); + bytes[0] ^= 0x80; + bytes + } + + fn from_cw_bytes(bytes: Self::Buf) -> Self { + let mut bytes = bytes; + bytes[0] ^= 0x80; + Self::from_be_bytes(bytes) + } + })* + } +} + +cw_int_keys!(for i8, i16, i32, i64, i128); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 0ab72b3a5..0dd50417e 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -4,6 +4,7 @@ mod helpers; mod indexed_map; mod indexed_snapshot; mod indexes; +mod int_key; mod item; mod iter_helpers; mod keys; From bdba35cb68838eb66885a84b949e206fe5877082 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 18:21:09 +0100 Subject: [PATCH 050/631] Use new integer key helpers --- packages/storage-plus/src/de.rs | 18 +++++++----- packages/storage-plus/src/keys.rs | 45 +++++++++++++++-------------- packages/storage-plus/src/prefix.rs | 9 +++--- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 1d69df74e..75981956d 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -6,6 +6,7 @@ use std::convert::TryInto; use cosmwasm_std::{Addr, StdError, StdResult}; +use crate::int_key::CwIntKey; use crate::keys::{IntKey, TimestampKey}; pub trait KeyDeserialize { @@ -106,7 +107,7 @@ macro_rules! integer_de { #[inline(always)] fn from_vec(value: Vec) -> StdResult { - Ok(<$t>::from_be_bytes(value.as_slice().try_into() + Ok(<$t>::from_cw_bytes(value.as_slice().try_into() .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) } })* @@ -122,7 +123,7 @@ macro_rules! intkey_de { #[inline(always)] fn from_vec(value: Vec) -> StdResult { - Ok(<$t>::from_be_bytes(value.as_slice().try_into() + Ok(<$t>::from_cw_bytes(value.as_slice().try_into() .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) } })* @@ -232,11 +233,14 @@ mod test { #[test] fn deserialize_integer_works() { assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); - assert_eq!(>::from_slice(&[128]).unwrap(), -1i8 << 7); + assert_eq!( + >::from_slice(&[128]).unwrap(), + ((-1i8 << 7) as u8 ^ 0x80) as i8 + ); assert_eq!(>::from_slice(&[1, 0]).unwrap(), 1u16 << 8); assert_eq!( >::from_slice(&[128, 0]).unwrap(), - -1i16 << (8 + 7) + ((-1i16 << (8 + 7)) as u16 ^ 0x8000) as i16 ); assert_eq!( >::from_slice(&[1, 0, 0, 0]).unwrap(), @@ -244,7 +248,7 @@ mod test { ); assert_eq!( >::from_slice(&[128, 0, 0, 0]).unwrap(), - -1i32 << (3 * 8 + 7) + ((-1i32 << (3 * 8 + 7)) as u32 ^ 0x80000000) as i32 ); assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), @@ -252,7 +256,7 @@ mod test { ); assert_eq!( >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - -1i64 << (7 * 8 + 7) + ((-1i64 << (7 * 8 + 7)) as u64 ^ 0x8000000000000000) as i64 ); assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), @@ -263,7 +267,7 @@ mod test { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]) .unwrap(), - -1i128 + (-1i128 as u128 ^ 0x80000000000000000000000000000000u128) as i128 ); } diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 08cb4caf9..ff318cde0 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -6,6 +6,7 @@ use std::marker::PhantomData; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; +use crate::int_key::CwIntKey; use crate::Endian; #[derive(Debug)] @@ -284,7 +285,7 @@ macro_rules! integer_key { type SuperSuffix = Self; fn key(&self) -> Vec { - vec![Key::$v(self.to_be_bytes())] + vec![Key::$v(self.to_cw_bytes())] } })* } @@ -296,7 +297,7 @@ macro_rules! integer_prefix { (for $($t:ty, $v:tt),+) => { $(impl<'a> Prefixer<'a> for $t { fn prefix(&self) -> Vec { - vec![Key::$v(self.to_be_bytes())] + vec![Key::$v(self.to_cw_bytes())] } })* } @@ -361,16 +362,16 @@ pub struct IntKey { pub data: PhantomData, } -impl IntKey { +impl IntKey { pub fn new(val: T) -> Self { IntKey { - wrapped: val.to_be_bytes().into(), + wrapped: val.to_cw_bytes().into(), data: PhantomData, } } } -impl From for IntKey { +impl From for IntKey { fn from(val: T) -> Self { IntKey::new(val) } @@ -440,7 +441,7 @@ mod test { let k: U64Key = 134u64.into(); let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(134u64.to_be_bytes(), path[0].as_ref()); + assert_eq!(134u64.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -448,7 +449,7 @@ mod test { let k: U32Key = 4242u32.into(); let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242u32.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242u32.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -456,12 +457,12 @@ mod test { let k: u8 = 42u8; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(42u8.to_be_bytes(), path[0].as_ref()); + assert_eq!(42u8.to_cw_bytes(), path[0].as_ref()); let k: i8 = 42i8; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(42i8.to_be_bytes(), path[0].as_ref()); + assert_eq!(42i8.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -469,12 +470,12 @@ mod test { let k: u16 = 4242u16; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242u16.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242u16.to_cw_bytes(), path[0].as_ref()); let k: i16 = 4242i16; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242i16.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242i16.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -482,12 +483,12 @@ mod test { let k: u32 = 4242u32; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242u32.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242u32.to_cw_bytes(), path[0].as_ref()); let k: i32 = 4242i32; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242i32.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242i32.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -495,12 +496,12 @@ mod test { let k: u64 = 4242u64; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242u64.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242u64.to_cw_bytes(), path[0].as_ref()); let k: i64 = 4242i64; let path = k.key(); assert_eq!(1, path.len()); - assert_eq!(4242i64.to_be_bytes(), path[0].as_ref()); + assert_eq!(4242i64.to_cw_bytes(), path[0].as_ref()); } #[test] @@ -557,8 +558,8 @@ mod test { assert_eq!(2, path.len()); assert_eq!(4, path[0].as_ref().len()); assert_eq!(8, path[1].as_ref().len()); - assert_eq!(path[0].as_ref(), 123u32.to_be_bytes()); - assert_eq!(path[1].as_ref(), 87654u64.to_be_bytes()); + assert_eq!(path[0].as_ref(), 123u32.to_cw_bytes()); + assert_eq!(path[1].as_ref(), 87654u64.to_cw_bytes()); } #[test] @@ -568,8 +569,8 @@ mod test { assert_eq!(2, path.len()); assert_eq!(4, path[0].as_ref().len()); assert_eq!(8, path[1].as_ref().len()); - assert_eq!(path[0].as_ref(), 123u32.to_be_bytes()); - assert_eq!(path[1].as_ref(), 87654u64.to_be_bytes()); + assert_eq!(path[0].as_ref(), 123u32.to_cw_bytes()); + assert_eq!(path[1].as_ref(), 87654u64.to_cw_bytes()); } #[test] @@ -625,7 +626,7 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i8, &[u8]) = (123, b"random"); - let one: Vec = vec![123]; + let one: Vec = vec![123 + 128]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } @@ -638,7 +639,7 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i16, &[u8]) = (12345, b"random"); - let one: Vec = vec![48, 57]; + let one: Vec = vec![48 + 128, 57]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } @@ -651,7 +652,7 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i64, &[u8]) = (12345, b"random"); - let one: Vec = vec![0, 0, 0, 0, 0, 0, 48, 57]; + let one: Vec = vec![128, 0, 0, 0, 0, 0, 48, 57]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 5c210052a..38e4b7c78 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -8,6 +8,7 @@ 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}; @@ -34,13 +35,13 @@ impl Bound { } /// Turns an int, like Option into an inclusive bound - pub fn inclusive_int(limit: T) -> Self { - Bound::Inclusive(limit.to_be_bytes().into()) + pub fn inclusive_int(limit: T) -> Self { + Bound::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_be_bytes().into()) + pub fn exclusive_int(limit: T) -> Self { + Bound::Exclusive(limit.to_cw_bytes().into()) } } From 00f0af851ca07f0b95ba1137a3d935bd8f536557 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 18:32:45 +0100 Subject: [PATCH 051/631] Add positive integer signed integer key tests --- packages/storage-plus/src/de.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 75981956d..6106aa088 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -237,10 +237,18 @@ mod test { >::from_slice(&[128]).unwrap(), ((-1i8 << 7) as u8 ^ 0x80) as i8 ); + assert_eq!( + >::from_slice(&[127]).unwrap(), + (127 ^ 0x80) as i8 + ); assert_eq!(>::from_slice(&[1, 0]).unwrap(), 1u16 << 8); assert_eq!( >::from_slice(&[128, 0]).unwrap(), - ((-1i16 << (8 + 7)) as u16 ^ 0x8000) as i16 + ((-1i16 << 15) as u16 ^ 0x8000) as i16 + ); + assert_eq!( + >::from_slice(&[127, 255]).unwrap(), + (((1u16 << 15) - 1) ^ 0x8000) as i16 ); assert_eq!( >::from_slice(&[1, 0, 0, 0]).unwrap(), @@ -248,7 +256,11 @@ mod test { ); assert_eq!( >::from_slice(&[128, 0, 0, 0]).unwrap(), - ((-1i32 << (3 * 8 + 7)) as u32 ^ 0x80000000) as i32 + ((-1i32 << 31) as u32 ^ 0x80000000) as i32 + ); + assert_eq!( + >::from_slice(&[127, 255, 255, 255]).unwrap(), + (((1u32 << 31) - 1) ^ 0x80000000) as i32 ); assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), @@ -256,7 +268,11 @@ mod test { ); assert_eq!( >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - ((-1i64 << (7 * 8 + 7)) as u64 ^ 0x8000000000000000) as i64 + ((-1i64 << 63) as u64 ^ 0x8000000000000000) as i64 + ); + assert_eq!( + >::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), + (((1u64 << 63) - 1) ^ 0x8000000000000000) as i64 ); assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), @@ -267,7 +283,7 @@ mod test { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]) .unwrap(), - (-1i128 as u128 ^ 0x80000000000000000000000000000000u128) as i128 + (-1i128 as u128 ^ 0x80000000000000000000000000000000) as i128 ); } From 495ae24f7992e03f7746ea7f2c5b83c67f2fa2d1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 20:55:14 +0100 Subject: [PATCH 052/631] Non-mutable, branchless signed int key conversions --- packages/storage-plus/src/int_key.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 8462f7d68..b2475938f 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -3,6 +3,7 @@ use std::mem; /// Our int keys are simply the Big-endian representation bytes for unsigned ints, /// but "sign-flipped" (xored msb) Big-endian bytes for signed ints. /// So that the representation of signed integers is correctly ordered lexicographically. +// TODO: Rename to `IntKey` when deprecating actual `IntKey` pub trait CwIntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; @@ -34,15 +35,11 @@ macro_rules! cw_int_keys { type Buf = [u8; mem::size_of::<$t>()]; fn to_cw_bytes(&self) -> Self::Buf { - let mut bytes = self.to_be_bytes(); - bytes[0] ^= 0x80; - bytes + ((*self as u128 ^ <$t>::MIN as u128) as $t).to_be_bytes() } fn from_cw_bytes(bytes: Self::Buf) -> Self { - let mut bytes = bytes; - bytes[0] ^= 0x80; - Self::from_be_bytes(bytes) + (Self::from_be_bytes(bytes) as u128 ^ <$t>::MIN as u128) as _ } })* } From c211470ac3f51cd7fe6069c5d74afa729faa2f18 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 20:56:05 +0100 Subject: [PATCH 053/631] Type-sized casts signed int key conversions --- packages/storage-plus/src/int_key.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index b2475938f..da099b1d0 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -30,19 +30,19 @@ macro_rules! cw_uint_keys { cw_uint_keys!(for u8, u16, u32, u64, u128); macro_rules! cw_int_keys { - (for $($t:ty),+) => { + (for $($t:ty, $ut:ty),+) => { $(impl CwIntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; fn to_cw_bytes(&self) -> Self::Buf { - ((*self as u128 ^ <$t>::MIN as u128) as $t).to_be_bytes() + (*self as $ut ^ <$t>::MIN as $ut).to_be_bytes() } fn from_cw_bytes(bytes: Self::Buf) -> Self { - (Self::from_be_bytes(bytes) as u128 ^ <$t>::MIN as u128) as _ + (Self::from_be_bytes(bytes) as $ut ^ <$t>::MIN as $ut) as _ } })* } } -cw_int_keys!(for i8, i16, i32, i64, i128); +cw_int_keys!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); From 525390d17b82e40be57755bcc726d4bfcac37221 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 21:02:50 +0100 Subject: [PATCH 054/631] Adapt packages to cw int keys --- packages/storage-plus/src/map.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 320c7a64c..b85c69010 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -254,6 +254,8 @@ mod test { #[cfg(feature = "iterator")] use cosmwasm_std::{Order, StdResult}; + use crate::int_key::CwIntKey; + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { pub name: String, @@ -297,7 +299,7 @@ mod test { ); assert_eq!(b"triple".to_vec().as_slice(), &key[2..8]); assert_eq!(b"john".to_vec().as_slice(), &key[10..14]); - assert_eq!(8u8.to_be_bytes(), &key[16..17]); + assert_eq!(8u8.to_cw_bytes(), &key[16..17]); assert_eq!(b"pedro".to_vec().as_slice(), &key[17..]); } From c2c1a0c8464885034e3b17375e43cc417d62462c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 21:12:19 +0100 Subject: [PATCH 055/631] Publish cw int key trait --- packages/storage-plus/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 0dd50417e..77665e2f7 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -29,6 +29,7 @@ pub use item::Item; #[allow(deprecated)] pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; // TODO: Remove along with `IntKey` +pub use int_key::CwIntKey; #[allow(deprecated)] pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; pub use map::Map; From fc708d4babe8190936b877c55a574614e606f4d8 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 21:17:09 +0100 Subject: [PATCH 056/631] Remove deprecated functions --- contracts/cw3-fixed-multisig/src/state.rs | 12 +----------- contracts/cw3-flex-multisig/src/state.rs | 14 +------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index e3b35c27b..b596ef605 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -1,8 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; -use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Empty, StdError, StdResult, Storage}; +use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Empty, StdResult, Storage}; use cw3::{Status, Vote}; use cw_storage_plus::{Item, Map}; @@ -66,12 +65,3 @@ pub fn next_id(store: &mut dyn Storage) -> StdResult { PROPOSAL_COUNT.save(store, &id)?; Ok(id) } - -pub fn parse_id(data: &[u8]) -> StdResult { - match data[0..8].try_into() { - Ok(bytes) => Ok(u64::from_be_bytes(bytes)), - Err(_) => Err(StdError::generic_err( - "Corrupted data found. 8 byte expected.", - )), - } -} diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 844ec8408..013757beb 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,10 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; -use cosmwasm_std::{ - Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdError, StdResult, Storage, Uint128, -}; +use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; use cw3::{Status, Vote}; use cw4::Cw4Contract; @@ -162,15 +159,6 @@ pub fn next_id(store: &mut dyn Storage) -> StdResult { Ok(id) } -pub fn parse_id(data: &[u8]) -> StdResult { - match data[0..8].try_into() { - Ok(bytes) => Ok(u64::from_be_bytes(bytes)), - Err(_) => Err(StdError::generic_err( - "Corrupted data found. 8 byte expected.", - )), - } -} - #[cfg(test)] mod test { use super::*; From a69865660d706d624a3198a4b41ff6ee0d82dac6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 21:23:14 +0100 Subject: [PATCH 057/631] Improve docs / comments --- packages/storage-plus/src/int_key.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index da099b1d0..918110345 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -1,9 +1,10 @@ use std::mem; -/// Our int keys are simply the Big-endian representation bytes for unsigned ints, -/// but "sign-flipped" (xored msb) Big-endian bytes for signed ints. -/// So that the representation of signed integers is correctly ordered lexicographically. -// TODO: Rename to `IntKey` when deprecating actual `IntKey` +/// Our int keys are simply the big-endian representation bytes for unsigned ints, +/// but "sign-flipped" (xored msb) big-endian bytes for signed ints. +/// +/// So that the representation of signed integers is in the right lexicographical order. +// TODO: Rename to `IntKey` when deprecating current `IntKey` pub trait CwIntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; From 2d81dca15fa32b8fa2c7becd7ba63883524da3a6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 15 Dec 2021 21:35:39 +0100 Subject: [PATCH 058/631] Add cw int key unit tests --- packages/storage-plus/src/int_key.rs | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 918110345..9aa85e9f9 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -47,3 +47,80 @@ macro_rules! cw_int_keys { } cw_int_keys!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn x8_int_key_works() { + let k: u8 = 42u8; + assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); + + let k: i8 = 42i8; + assert_eq!(k.to_cw_bytes(), (k as u8 ^ 0x80).to_be_bytes()); + + let k: i8 = -42i8; + assert_eq!(k.to_cw_bytes(), (k as u8 ^ 0x80).to_be_bytes()); + } + + #[test] + fn x16_int_key_works() { + let k: u16 = 4243u16; + assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); + + let k: i16 = 4445i16; + assert_eq!(k.to_cw_bytes(), (k as u16 ^ 0x8000).to_be_bytes()); + + let k: i16 = -4748i16; + assert_eq!(k.to_cw_bytes(), (k as u16 ^ 0x8000).to_be_bytes()); + } + + #[test] + fn x32_int_key_works() { + let k: u32 = 424344u32; + assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); + + let k: i32 = 454647i32; + assert_eq!(k.to_cw_bytes(), (k as u32 ^ 0x80000000).to_be_bytes()); + + let k: i32 = -484950i32; + assert_eq!(k.to_cw_bytes(), (k as u32 ^ 0x80000000).to_be_bytes()); + } + + #[test] + fn x64_int_key_works() { + let k: u64 = 42434445u64; + assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); + + let k: i64 = 46474849i64; + assert_eq!( + k.to_cw_bytes(), + (k as u64 ^ 0x8000000000000000).to_be_bytes() + ); + + let k: i64 = -50515253i64; + assert_eq!( + k.to_cw_bytes(), + (k as u64 ^ 0x8000000000000000).to_be_bytes() + ); + } + + #[test] + fn x128_int_key_works() { + let k: u128 = 4243444546u128; + assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); + + let k: i128 = 4748495051i128; + assert_eq!( + k.to_cw_bytes(), + (k as u128 ^ 0x80000000000000000000000000000000).to_be_bytes() + ); + + let k: i128 = -5253545556i128; + assert_eq!( + k.to_cw_bytes(), + (k as u128 ^ 0x80000000000000000000000000000000).to_be_bytes() + ); + } +} From a3d5c4ce3cef5ea26da58b029e12c6d196d0515b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Dec 2021 06:48:44 +0100 Subject: [PATCH 059/631] Add inline attribute to int key helpers --- packages/storage-plus/src/int_key.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 9aa85e9f9..70c558c9d 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -17,10 +17,12 @@ macro_rules! cw_uint_keys { $(impl CwIntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; + #[inline] fn to_cw_bytes(&self) -> Self::Buf { self.to_be_bytes() } + #[inline] fn from_cw_bytes(bytes: Self::Buf) -> Self { Self::from_be_bytes(bytes) } @@ -35,10 +37,12 @@ macro_rules! cw_int_keys { $(impl CwIntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; + #[inline] fn to_cw_bytes(&self) -> Self::Buf { (*self as $ut ^ <$t>::MIN as $ut).to_be_bytes() } + #[inline] fn from_cw_bytes(bytes: Self::Buf) -> Self { (Self::from_be_bytes(bytes) as $ut ^ <$t>::MIN as $ut) as _ } From 1e1f8c441065b588dc5f6f306431ab928252175d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Dec 2021 11:27:57 +0100 Subject: [PATCH 060/631] Update TODO --- packages/storage-plus/src/int_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 70c558c9d..35c3cb69b 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -4,7 +4,7 @@ use std::mem; /// but "sign-flipped" (xored msb) big-endian bytes for signed ints. /// /// So that the representation of signed integers is in the right lexicographical order. -// TODO: Rename to `IntKey` when deprecating current `IntKey` +// TODO: Rename to `IntKey` after deprecating current `IntKey` (https://github.com/CosmWasm/cw-plus/issues/570) pub trait CwIntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; From a993938f49c8a4cdba8ad84befd559bab6d57a67 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Dec 2021 11:31:49 +0100 Subject: [PATCH 061/631] Clarify signed int keys format in tests --- packages/storage-plus/src/keys.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index ff318cde0..63bedba2e 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -626,7 +626,8 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i8, &[u8]) = (123, b"random"); - let one: Vec = vec![123 + 128]; + // Signed int keys are "sign-flipped" + let one: Vec = vec![123 ^ 0x80]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } @@ -639,7 +640,8 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i16, &[u8]) = (12345, b"random"); - let one: Vec = vec![48 + 128, 57]; + // Signed int keys are "sign-flipped" + let one: Vec = vec![48 ^ 0x80, 57]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } @@ -652,7 +654,9 @@ mod test { assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); let pair: (i64, &[u8]) = (12345, b"random"); - let one: Vec = vec![128, 0, 0, 0, 0, 0, 48, 57]; + // Signed int keys are "sign-flipped" + #[allow(clippy::identity_op)] + let one: Vec = vec![0 ^ 0x80, 0, 0, 0, 0, 0, 48, 57]; let two: Vec = b"random".to_vec(); assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); } From 7208d847535a76d182d4520a8d3f44ae5402c3e7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Dec 2021 22:57:53 +0100 Subject: [PATCH 062/631] Add signed int key range tests --- packages/storage-plus/src/map.rs | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index b85c69010..5bb9e91e5 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -265,6 +265,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: Map = Map::new("signed_id"); const ALLOWANCE: Map<(&[u8], &[u8]), u64> = Map::new("allow"); @@ -570,6 +572,69 @@ mod test { assert_eq!(all, vec![(1234, data)]); } + #[test] + #[cfg(feature = "iterator")] + fn range_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 + .range(&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 + .range( + &store, + Some(Bound::inclusive_int(-56i32)), + 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 + .range( + &store, + Some(Bound::inclusive_int(-55i32)), + Some(Bound::inclusive_int(50i32)), + Order::Descending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(50, data3)]); + } + #[test] #[cfg(feature = "iterator")] fn range_raw_composite_key() { From c19c45ec5729284d9320eac8c48e475e8cb3ba10 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 17 Dec 2021 11:30:56 +0100 Subject: [PATCH 063/631] Use explicit expected results in tests --- packages/storage-plus/src/de.rs | 59 +++++++++++++++++---------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 6106aa088..6990518ee 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -233,57 +233,58 @@ mod test { #[test] fn deserialize_integer_works() { assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); - assert_eq!( - >::from_slice(&[128]).unwrap(), - ((-1i8 << 7) as u8 ^ 0x80) as i8 - ); - assert_eq!( - >::from_slice(&[127]).unwrap(), - (127 ^ 0x80) as i8 - ); - assert_eq!(>::from_slice(&[1, 0]).unwrap(), 1u16 << 8); - assert_eq!( - >::from_slice(&[128, 0]).unwrap(), - ((-1i16 << 15) as u16 ^ 0x8000) as i16 - ); - assert_eq!( - >::from_slice(&[127, 255]).unwrap(), - (((1u16 << 15) - 1) ^ 0x8000) as i16 - ); + assert_eq!(>::from_slice(&[127]).unwrap(), -1i8); + assert_eq!(>::from_slice(&[128]).unwrap(), 0i8); + + assert_eq!(>::from_slice(&[1, 0]).unwrap(), 256u16); + assert_eq!(>::from_slice(&[128, 0]).unwrap(), 0i16); + assert_eq!(>::from_slice(&[127, 255]).unwrap(), -1i16); + assert_eq!( >::from_slice(&[1, 0, 0, 0]).unwrap(), - 1u32 << (3 * 8) - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0]).unwrap(), - ((-1i32 << 31) as u32 ^ 0x80000000) as i32 + 16777216u32 ); + assert_eq!(>::from_slice(&[128, 0, 0, 0]).unwrap(), 0i32); assert_eq!( >::from_slice(&[127, 255, 255, 255]).unwrap(), - (((1u32 << 31) - 1) ^ 0x80000000) as i32 + -1i32 ); + assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 1u64 << (7 * 8) + 72057594037927936u64 ); assert_eq!( >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - ((-1i64 << 63) as u64 ^ 0x8000000000000000) as i64 + 0i64 ); assert_eq!( >::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), - (((1u64 << 63) - 1) ^ 0x8000000000000000) as i64 + -1i64 ); + assert_eq!( >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 1u128 << (15 * 8) + 1329227995784915872903807060280344576u128 + ); + assert_eq!( + >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + .unwrap(), + 0i128 + ); + assert_eq!( + >::from_slice(&[ + 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ]) + .unwrap(), + -1i128 ); assert_eq!( >::from_slice(&[ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]) .unwrap(), - (-1i128 as u128 ^ 0x80000000000000000000000000000000) as i128 + 170141183460469231731687303715884105727i128, ); } @@ -306,7 +307,7 @@ mod test { fn deserialize_timestamp_works() { assert_eq!( ::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 1u64 << (7 * 8) + 72057594037927936 ); } From 1548f22eb690e4d837fd0d713d54c5cccc05acf1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 17 Dec 2021 11:31:51 +0100 Subject: [PATCH 064/631] Add naked int deserialization tests --- packages/storage-plus/src/de.rs | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 6990518ee..60f6fcb57 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -230,6 +230,54 @@ mod test { )); } + #[test] + fn deserialize_naked_integer_works() { + assert_eq!(u8::from_slice(&[1]).unwrap(), 1u8); + assert_eq!(i8::from_slice(&[127]).unwrap(), -1i8); + assert_eq!(i8::from_slice(&[128]).unwrap(), 0i8); + + assert_eq!(u16::from_slice(&[1, 0]).unwrap(), 256u16); + assert_eq!(i16::from_slice(&[128, 0]).unwrap(), 0i16); + assert_eq!(i16::from_slice(&[127, 255]).unwrap(), -1i16); + + assert_eq!(u32::from_slice(&[1, 0, 0, 0]).unwrap(), 16777216u32); + assert_eq!(i32::from_slice(&[128, 0, 0, 0]).unwrap(), 0i32); + assert_eq!(i32::from_slice(&[127, 255, 255, 255]).unwrap(), -1i32); + + assert_eq!( + u64::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + 72057594037927936u64 + ); + assert_eq!(i64::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), 0i64); + assert_eq!( + i64::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), + -1i64 + ); + + assert_eq!( + u128::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + 1329227995784915872903807060280344576u128 + ); + assert_eq!( + i128::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + 0i128 + ); + assert_eq!( + i128::from_slice(&[ + 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ]) + .unwrap(), + -1i128 + ); + assert_eq!( + i128::from_slice(&[ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ]) + .unwrap(), + 170141183460469231731687303715884105727i128, + ); + } + #[test] fn deserialize_integer_works() { assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); From fd84dcd2a084de12b9809532d9c24d12ddaaede2 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 17 Dec 2021 12:34:03 +0100 Subject: [PATCH 065/631] Use explicit expected results in int key tests --- packages/storage-plus/src/int_key.rs | 78 ++++++++++++---------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 35c3cb69b..e2633bb83 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -58,73 +58,63 @@ mod test { #[test] fn x8_int_key_works() { - let k: u8 = 42u8; - assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); - - let k: i8 = 42i8; - assert_eq!(k.to_cw_bytes(), (k as u8 ^ 0x80).to_be_bytes()); - - let k: i8 = -42i8; - assert_eq!(k.to_cw_bytes(), (k as u8 ^ 0x80).to_be_bytes()); + assert_eq!(0x42u8.to_cw_bytes(), [0x42]); + assert_eq!(0x42i8.to_cw_bytes(), [0xc2]); + assert_eq!((-0x3ei8).to_cw_bytes(), [0x42]); } #[test] fn x16_int_key_works() { - let k: u16 = 4243u16; - assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); - - let k: i16 = 4445i16; - assert_eq!(k.to_cw_bytes(), (k as u16 ^ 0x8000).to_be_bytes()); - - let k: i16 = -4748i16; - assert_eq!(k.to_cw_bytes(), (k as u16 ^ 0x8000).to_be_bytes()); + assert_eq!(0x4243u16.to_cw_bytes(), [0x42, 0x43]); + assert_eq!(0x4243i16.to_cw_bytes(), [0xc2, 0x43]); + assert_eq!((-0x3dbdi16).to_cw_bytes(), [0x42, 0x43]); } #[test] fn x32_int_key_works() { - let k: u32 = 424344u32; - assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); - - let k: i32 = 454647i32; - assert_eq!(k.to_cw_bytes(), (k as u32 ^ 0x80000000).to_be_bytes()); - - let k: i32 = -484950i32; - assert_eq!(k.to_cw_bytes(), (k as u32 ^ 0x80000000).to_be_bytes()); + assert_eq!(0x424344u32.to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]); + assert_eq!(0x424344i32.to_cw_bytes(), [0x80, 0x42, 0x43, 0x44]); + assert_eq!((-0x7fbdbcbci32).to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]); } #[test] fn x64_int_key_works() { - let k: u64 = 42434445u64; - assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); - - let k: i64 = 46474849i64; assert_eq!( - k.to_cw_bytes(), - (k as u64 ^ 0x8000000000000000).to_be_bytes() + 0x42434445u64.to_cw_bytes(), + [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] + ); + assert_eq!( + 0x42434445i64.to_cw_bytes(), + [0x80, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] ); - - let k: i64 = -50515253i64; assert_eq!( - k.to_cw_bytes(), - (k as u64 ^ 0x8000000000000000).to_be_bytes() + (-0x7fffffffbdbcbbbbi64).to_cw_bytes(), + [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] ); } #[test] fn x128_int_key_works() { - let k: u128 = 4243444546u128; - assert_eq!(k.to_cw_bytes(), k.to_be_bytes()); - - let k: i128 = 4748495051i128; assert_eq!( - k.to_cw_bytes(), - (k as u128 ^ 0x80000000000000000000000000000000).to_be_bytes() + 0x4243444546u128.to_cw_bytes(), + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, + 0x45, 0x46 + ] + ); + assert_eq!( + 0x4243444546i128.to_cw_bytes(), + [ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, + 0x45, 0x46 + ] ); - - let k: i128 = -5253545556i128; assert_eq!( - k.to_cw_bytes(), - (k as u128 ^ 0x80000000000000000000000000000000).to_be_bytes() + (-0x7fffffffffffffffffffffbdbcbbbabai128).to_cw_bytes(), + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, + 0x45, 0x46 + ] ); } } From dcf66208de20e7af51c12f6049aa07555324f882 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 17 Dec 2021 12:41:20 +0100 Subject: [PATCH 066/631] Add unsigned / signed int keys order tests --- packages/storage-plus/src/int_key.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index e2633bb83..7f7713369 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -117,4 +117,15 @@ mod test { ] ); } + + #[test] + fn unsigned_int_key_order() { + assert!(0u32.to_cw_bytes() < 652u32.to_cw_bytes()); + } + + #[test] + fn signed_int_key_order() { + assert!((-321i32).to_cw_bytes() < 0i32.to_cw_bytes()); + assert!(0i32.to_cw_bytes() < 652i32.to_cw_bytes()); + } } From 0afdefc1ffb110fafdcb4858230486dcc05d6a5c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 5 Nov 2021 11:26:38 +0100 Subject: [PATCH 067/631] Make update_changelog use the latest version tag by default --- scripts/update_changelog.sh | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/scripts/update_changelog.sh b/scripts/update_changelog.sh index 62a17f520..09331e61e 100755 --- a/scripts/update_changelog.sh +++ b/scripts/update_changelog.sh @@ -2,29 +2,29 @@ ORIGINAL_OPTS=$* -OPTS=$(getopt -l "help,since-tag:,latest-tag,token:" -o "hlt" -- "$@") || exit 1 +OPTS=$(getopt -l "help,since-tag:,full,token:" -o "hft" -- "$@") || exit 1 eval set -- "$OPTS" while true do case $1 in -h|--help) - echo -e "Usage: $0 [-h|--help] [--since-tag ] [-l|--latest-tag] [-t|--token ] + echo -e "Usage: $0 [-h|--help] [-f|--full] [--since-tag ] [-t|--token ] -h, --help Display help ---since-tag Process changes since tag --l, --latest-tag Process changes since latest tag +-f, --full Process changes since the beginning (by default: since latest git version tag) +--since-tag Process changes since git version tag (by default: since latest git version tag) --token Pass changelog github token " exit 0 ;; ---since-tag) + --since-tag) shift TAG="$1" ;; --l|--latest-tag) - TAG=$(git tag --sort=creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | tail -1) - ORIGINAL_OPTS=$(echo "$ORIGINAL_OPTS" | sed "s/\\B$1\\b/--since-tag $TAG/") + -f|--full) + TAG="" + ORIGINAL_OPTS=$(echo "$ORIGINAL_OPTS" | sed "s/\\B$1\\b//") ;; ---) + --) shift break ;; @@ -32,8 +32,21 @@ esac shift done + +if [ -z "$TAG" ] +then + # Use latest git version tag + TAG=$(git tag --sort=creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | tail -1) + ORIGINAL_OPTS="$ORIGINAL_OPTS --since-tag $TAG" +fi + +echo "Git version tag: $TAG" + cp CHANGELOG.md /tmp/CHANGELOG.md.$$ -sed -i -n "/^## \\[$TAG\\]/,\$p" CHANGELOG.md +# Consolidate tag for matching changelog entries +TAG=$(echo "$TAG" | sed 's/-\([A-Za-z]*\)[^A-Za-z]*/-\1/') +echo "Consolidated tag: $TAG" +sed -i -n "/^## \\[${TAG}[^]]*\\]/,\$p" CHANGELOG.md github_changelog_generator -u CosmWasm -p cw-plus --base CHANGELOG.md $ORIGINAL_OPTS || cp /tmp/CHANGELOG.md.$$ CHANGELOG.md From 8a430d3da9027ead0df514e807e9620eb3e6fe03 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 21 Dec 2021 13:15:16 +0100 Subject: [PATCH 068/631] Update to cosmwasm 1.0.0-beta3 --- Cargo.lock | 80 ++++++++++++------------ contracts/cw1-subkeys/Cargo.toml | 4 +- contracts/cw1-whitelist-ng/Cargo.toml | 4 +- contracts/cw1-whitelist/Cargo.toml | 4 +- contracts/cw1155-base/Cargo.toml | 4 +- contracts/cw20-atomic-swap/Cargo.toml | 4 +- contracts/cw20-base/Cargo.toml | 4 +- contracts/cw20-bonding/Cargo.toml | 4 +- contracts/cw20-escrow/Cargo.toml | 4 +- contracts/cw20-ics20/Cargo.toml | 4 +- contracts/cw20-merkle-airdrop/Cargo.toml | 4 +- contracts/cw20-staking/Cargo.toml | 4 +- contracts/cw3-fixed-multisig/Cargo.toml | 4 +- contracts/cw3-flex-multisig/Cargo.toml | 4 +- contracts/cw4-group/Cargo.toml | 4 +- contracts/cw4-stake/Cargo.toml | 4 +- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 4 +- packages/cw1155/Cargo.toml | 4 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 4 +- packages/multi-test/Cargo.toml | 4 +- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 2 +- 26 files changed, 86 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 295f5ee19..43fed7b8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.45" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" dependencies = [ "backtrace", ] @@ -133,9 +133,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta2" +version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c16b255449b3f5cd7fa4b79acd5225b5185655261087a3d8aaac44f88a0e23e9" +checksum = "a380b87642204557629c9b72988c47b55fbfe6d474960adba56b22331504956a" dependencies = [ "digest 0.9.0", "ed25519-zebra", @@ -146,18 +146,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta2" +version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abad1a6ff427a2f66890a4dce6354b4563cd07cee91a942300e011c921c09ed2" +checksum = "866713b2fe13f23038c7d8824c3059d1f28dd94685fb406d1533c4eeeefeefae" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0-beta2" +version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe52b19d45fe3f8359db6cc24df44dbe05e5ae32539afc0f5b7f790a21aa6fd0" +checksum = "818b928263c09a3269c2bed22494a62107a43ef87900e273af8ad2cb9f7e4440" dependencies = [ "schemars", "serde_json", @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.0.0-beta2" +version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1660ee3d5734672e1eb4f0ceda403e2d83345e15143a48845f340f3252ce99a6" +checksum = "8dbb9939b31441dfa9af3ec9740c8a24d585688401eff1b6b386abb7ad0d10a8" dependencies = [ "base64", "cosmwasm-crypto", @@ -181,9 +181,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0-beta2" +version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3b4efe3b4f86df668520a02e9a29c23eea99b64dfcacb0e59b98346418af7f" +checksum = "b4a4e55f0d64fed54cd2202301b8d466af8de044589247dabd77a4222f52f749" dependencies = [ "cosmwasm-std", "serde", @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" dependencies = [ "const-oid", ] @@ -806,18 +806,18 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "k256" @@ -833,9 +833,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.107" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "memchr" @@ -895,9 +895,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" dependencies = [ "unicode-xid", ] @@ -954,9 +954,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353775f96a1f400edcca737f843cb201af3645912e741e64456a257c770173e8" +checksum = "71b5a9625a7e6060b23db692facf49082cc78889a7e6ac94a735356ae49db4b0" dependencies = [ "arrayvec", "num-traits", @@ -971,15 +971,15 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "schemars" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271ac0c667b8229adf70f0f957697c96fafd7486ab7481e15dc5e45e3e6a4368" +checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" dependencies = [ "dyn-clone", "schemars_derive", @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ebda811090b257411540779860bc09bf321bc587f58d2c5864309d1566214e7" +checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" dependencies = [ "proc-macro2", "quote", @@ -1007,27 +1007,27 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50eef3672ec8fa45f3457fd423ba131117786784a895548021976117c1ded449" +checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -1047,9 +1047,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.70" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", @@ -1114,9 +1114,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 37af477d8..acdc2d8db 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -23,7 +23,7 @@ utils = { path = "../../packages/utils", version = "0.10.3" } cw1 = { path = "../../packages/cw1", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 820636d96..e439b6264 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -25,7 +25,7 @@ multitest = ["cw-multi-test", "anyhow"] utils = { path = "../../packages/utils", version = "0.10.3" } cw1 = { path = "../../packages/cw1", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -36,6 +36,6 @@ anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 524e9e3fc..22d7a9218 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw1 = { path = "../../packages/cw1", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 3dd077bbd..0e9859c4d 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -22,10 +22,10 @@ utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw1155 = { path = "../../packages/cw1155", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-atomic-swap/Cargo.toml b/contracts/cw20-atomic-swap/Cargo.toml index 99f82105a..7da558616 100644 --- a/contracts/cw20-atomic-swap/Cargo.toml +++ b/contracts/cw20-atomic-swap/Cargo.toml @@ -18,7 +18,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -27,4 +27,4 @@ hex = "0.3.1" sha2 = "0.8.0" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index b0c3a6785..dbd87339a 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -22,10 +22,10 @@ utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-bonding/Cargo.toml b/contracts/cw20-bonding/Cargo.toml index 257d64fe5..4479a7f67 100644 --- a/contracts/cw20-bonding/Cargo.toml +++ b/contracts/cw20-bonding/Cargo.toml @@ -25,7 +25,7 @@ cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } cw20-base = { path = "../../contracts/cw20-base", version = "0.10.3", features = ["library"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta", default-features = false, features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta3", default-features = false, features = ["staking"] } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -34,4 +34,4 @@ integer-sqrt = { version = "0.1.5" } integer-cbrt = { version = "0.1.2" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-escrow/Cargo.toml b/contracts/cw20-escrow/Cargo.toml index 73ad16006..9727002a8 100644 --- a/contracts/cw20-escrow/Cargo.toml +++ b/contracts/cw20-escrow/Cargo.toml @@ -21,13 +21,13 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } cw20-base = { path = "../cw20-base", version = "0.10.3", features = ["library"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 91b6f38f0..53443d2a7 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -21,11 +21,11 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta", features = ["stargate"] } +cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-merkle-airdrop/Cargo.toml b/contracts/cw20-merkle-airdrop/Cargo.toml index 3fd176381..f9ef8cc9c 100644 --- a/contracts/cw20-merkle-airdrop/Cargo.toml +++ b/contracts/cw20-merkle-airdrop/Cargo.toml @@ -22,7 +22,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ hex = "0.4" sha2 = { version = "0.9.5", default-features = false } [dev-dependencies] -cosmwasm-schema = "1.0.0-beta" +cosmwasm-schema = "1.0.0-beta3" serde_json = "1.0" diff --git a/contracts/cw20-staking/Cargo.toml b/contracts/cw20-staking/Cargo.toml index 75ba91acc..e3effd870 100644 --- a/contracts/cw20-staking/Cargo.toml +++ b/contracts/cw20-staking/Cargo.toml @@ -25,11 +25,11 @@ cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } cw20-base = { path = "../../contracts/cw20-base", version = "0.10.3", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 2c5a917da..edab67af4 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -22,13 +22,13 @@ utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } cw20-base = { path = "../cw20-base", version = "0.10.3", features = ["library"] } cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 0d23ed746..d4d8e8608 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -23,12 +23,12 @@ cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } cw4-group = { path = "../cw4-group", version = "0.10.3" } cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 76c9ef038..a4dc89f4b 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -31,10 +31,10 @@ cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 1c07977e3..c07504e07 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -32,10 +32,10 @@ cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw20 = { path = "../../packages/cw20", version = "0.10.3" } cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index f41a29f16..5d99266c3 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } utils = { path = "../utils", version = "0.10.3" } cw-storage-plus = { path = "../storage-plus", version = "0.10.3" } schemars = "0.8.1" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 8fdefaf8f..75b2bcdbf 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 65a1ffc85..808ab5625 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] utils = { path = "../../packages/utils", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index d2e13ee6c..fc492461b 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta", default-features = false } +cosmwasm-std = { version = "1.0.0-beta3", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index eb618d550..fd47608e4 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] utils = { path = "../../packages/utils", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index dc07798b6..1e483eac8 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] utils = { path = "../../packages/utils", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 6c4329756..cd531b9da 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.10.3" } -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta" } +cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 4199b1390..e2f7c0dfe 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,8 +20,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] utils = { path = "../../packages/utils", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3"} -cosmwasm-std = { version = "1.0.0-beta", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } +cosmwasm-storage = { version = "1.0.0-beta3" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 2a6033b66..9635d6a49 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -14,6 +14,6 @@ default = ["iterator"] iterator = ["cosmwasm-std/iterator"] [dependencies] -cosmwasm-std = { version = "1.0.0-beta", default-features = false } +cosmwasm-std = { version = "1.0.0-beta3", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 1254a7f2b..f0a2ecd3d 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta" } +cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } From 0783a93fe82167c8a2274644961758caab2cc63f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 16:02:54 +0100 Subject: [PATCH 069/631] Remove schema outdated checks from CI --- .circleci/config.yml | 180 ------------------------------------------- 1 file changed, 180 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index de0e79fea..1965017e3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,15 +61,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -97,15 +88,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -133,15 +115,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -172,15 +145,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -208,15 +172,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -244,15 +199,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -280,15 +226,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -316,15 +253,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -352,15 +280,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -388,15 +307,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -424,15 +334,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -460,15 +361,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -496,15 +388,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -532,15 +415,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -568,15 +442,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure checked-in schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -655,15 +520,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -718,15 +574,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -755,15 +602,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -792,15 +630,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry @@ -829,15 +658,6 @@ jobs: - run: name: Build and run schema generator command: cargo schema --locked - - run: - name: Ensure schemas are up-to-date - command: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi - save_cache: paths: - /usr/local/cargo/registry From f4282d8e5035275ffd69dc875da2a8ec97611522 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 16:07:06 +0100 Subject: [PATCH 070/631] Add CI job to build and publish schemas on release tags --- .circleci/config.yml | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1965017e3..126a9c128 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,6 +38,12 @@ workflows: only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ branches: ignore: /.*/ + - build_and_upload_schemas: + filters: + tags: + only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ + branches: + ignore: /.*/ jobs: contract_cw1_subkeys: @@ -844,3 +850,49 @@ jobs: -n "$TITLE" -b "$BODY" \ -delete \ "$TAG" ./artifacts/ + + build_and_upload_schemas: + docker: + - image: rust:1.53.0 + working_directory: ~/project + steps: + - checkout: + path: ~/project + - run: + name: Create schemas directory + command: mkdir -p schemas + - run: + name: Install ghr + command: wget https://github.com/tcnksm/ghr/releases/download/v0.14.0/ghr_v0.14.0_linux_amd64.tar.gz -O - | tar -zxvf - -C /usr/local/bin --wildcards --strip-components 1 */ghr + - run: + name: Build and run schema generator for packages + command: | + for S in ./packages/*/examples/schema.rs + do + P=$(dirname $S)/.. + echo "Generating schema for $P ..." + (cd $P && cargo schema --locked && tar -zcf ~/project/schemas/$(basename $(pwd))_schema.tar.gz ./schema) + done + - run: + name: Build and run schema generator for contracts + command: | + for C in ./contracts/*/ + do + echo "Generating schema for $C ..." + (cd $C && cargo schema --locked && tar -zcf ~/project/schemas/$(basename $(pwd))_schema.tar.gz ./schema) + done + - run: + name: Show data + command: ls -l ./schemas + - run: + name: Publish schemas on GitHub + command: | + TAG="$CIRCLE_TAG" + TITLE="$TAG" + BODY="Attached there are some schemas and build artifacts generated at this tag. Those are for development purposes only! Please use crates.io to find the packages of this release." + ghr -t "$GITHUB_TOKEN" \ + -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ + -c "$CIRCLE_SHA1" \ + -n "$TITLE" -b "$BODY" \ + -replace \ + "$TAG" ./schemas/ From 7ef7abcf35cec61ec4f9103b95b1cad81e4b91a2 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 16:08:11 +0100 Subject: [PATCH 071/631] Remove package schemas from repo --- packages/cw1/schema/can_execute_response.json | 13 - packages/cw1/schema/execute_msg.json | 331 ----------- packages/cw1/schema/query_msg.json | 332 ----------- .../schema/approved_for_all_response.json | 97 ---- packages/cw1155/schema/balance_response.json | 19 - .../cw1155/schema/batch_balance_response.json | 22 - .../schema/cw1155_batch_receive_msg.json | 51 -- .../cw1155/schema/cw1155_execute_msg.json | 383 ------------- packages/cw1155/schema/cw1155_query_msg.json | 211 ------- .../cw1155/schema/cw1155_receive_msg.json | 44 -- .../schema/is_approved_for_all_response.json | 13 - .../cw1155/schema/token_info_response.json | 14 - packages/cw1155/schema/tokens_response.json | 17 - .../cw20/schema/all_accounts_response.json | 16 - .../cw20/schema/all_allowances_response.json | 99 ---- packages/cw20/schema/allowance_response.json | 81 --- packages/cw20/schema/balance_response.json | 19 - packages/cw20/schema/cw20_execute_msg.json | 442 --------------- packages/cw20/schema/cw20_query_msg.json | 168 ------ packages/cw20/schema/cw20_receive_msg.json | 32 -- .../cw20/schema/download_logo_response.json | 24 - .../cw20/schema/marketing_info_response.json | 73 --- packages/cw20/schema/minter_response.json | 30 - packages/cw20/schema/token_info_response.json | 33 -- packages/cw3/schema/execute_msg.json | 495 ---------------- .../cw3/schema/proposal_list_response.json | 527 ------------------ packages/cw3/schema/proposal_response.json | 513 ----------------- packages/cw3/schema/query_msg.json | 218 -------- packages/cw3/schema/threshold_response.json | 100 ---- packages/cw3/schema/vote_list_response.json | 49 -- packages/cw3/schema/vote_response.json | 50 -- packages/cw3/schema/voter_detail.json | 19 - packages/cw3/schema/voter_list_response.json | 35 -- packages/cw3/schema/voter_response.json | 15 - packages/cw4/schema/admin_response.json | 13 - packages/cw4/schema/cw4_execute_msg.json | 69 --- packages/cw4/schema/cw4_query_msg.json | 103 ---- .../cw4/schema/member_changed_hook_msg.json | 47 -- packages/cw4/schema/member_list_response.json | 36 -- packages/cw4/schema/member_response.json | 15 - .../cw4/schema/total_weight_response.json | 15 - 41 files changed, 4883 deletions(-) delete mode 100644 packages/cw1/schema/can_execute_response.json delete mode 100644 packages/cw1/schema/execute_msg.json delete mode 100644 packages/cw1/schema/query_msg.json delete mode 100644 packages/cw1155/schema/approved_for_all_response.json delete mode 100644 packages/cw1155/schema/balance_response.json delete mode 100644 packages/cw1155/schema/batch_balance_response.json delete mode 100644 packages/cw1155/schema/cw1155_batch_receive_msg.json delete mode 100644 packages/cw1155/schema/cw1155_execute_msg.json delete mode 100644 packages/cw1155/schema/cw1155_query_msg.json delete mode 100644 packages/cw1155/schema/cw1155_receive_msg.json delete mode 100644 packages/cw1155/schema/is_approved_for_all_response.json delete mode 100644 packages/cw1155/schema/token_info_response.json delete mode 100644 packages/cw1155/schema/tokens_response.json delete mode 100644 packages/cw20/schema/all_accounts_response.json delete mode 100644 packages/cw20/schema/all_allowances_response.json delete mode 100644 packages/cw20/schema/allowance_response.json delete mode 100644 packages/cw20/schema/balance_response.json delete mode 100644 packages/cw20/schema/cw20_execute_msg.json delete mode 100644 packages/cw20/schema/cw20_query_msg.json delete mode 100644 packages/cw20/schema/cw20_receive_msg.json delete mode 100644 packages/cw20/schema/download_logo_response.json delete mode 100644 packages/cw20/schema/marketing_info_response.json delete mode 100644 packages/cw20/schema/minter_response.json delete mode 100644 packages/cw20/schema/token_info_response.json delete mode 100644 packages/cw3/schema/execute_msg.json delete mode 100644 packages/cw3/schema/proposal_list_response.json delete mode 100644 packages/cw3/schema/proposal_response.json delete mode 100644 packages/cw3/schema/query_msg.json delete mode 100644 packages/cw3/schema/threshold_response.json delete mode 100644 packages/cw3/schema/vote_list_response.json delete mode 100644 packages/cw3/schema/vote_response.json delete mode 100644 packages/cw3/schema/voter_detail.json delete mode 100644 packages/cw3/schema/voter_list_response.json delete mode 100644 packages/cw3/schema/voter_response.json delete mode 100644 packages/cw4/schema/admin_response.json delete mode 100644 packages/cw4/schema/cw4_execute_msg.json delete mode 100644 packages/cw4/schema/cw4_query_msg.json delete mode 100644 packages/cw4/schema/member_changed_hook_msg.json delete mode 100644 packages/cw4/schema/member_list_response.json delete mode 100644 packages/cw4/schema/member_response.json delete mode 100644 packages/cw4/schema/total_weight_response.json diff --git a/packages/cw1/schema/can_execute_response.json b/packages/cw1/schema/can_execute_response.json deleted file mode 100644 index a11bb1c17..000000000 --- a/packages/cw1/schema/can_execute_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CanExecuteResponse", - "type": "object", - "required": [ - "can_execute" - ], - "properties": { - "can_execute": { - "type": "boolean" - } - } -} diff --git a/packages/cw1/schema/execute_msg.json b/packages/cw1/schema/execute_msg.json deleted file mode 100644 index f5d5419e2..000000000 --- a/packages/cw1/schema/execute_msg.json +++ /dev/null @@ -1,331 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Execute requests the contract to re-dispatch all these messages with the contract's address as sender. Every implementation has it's own logic to determine in", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "msgs" - ], - "properties": { - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw1/schema/query_msg.json b/packages/cw1/schema/query_msg.json deleted file mode 100644 index dd699df25..000000000 --- a/packages/cw1/schema/query_msg.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, from the given sender, before any further state changes, should also succeed.", - "type": "object", - "required": [ - "can_execute" - ], - "properties": { - "can_execute": { - "type": "object", - "required": [ - "msg", - "sender" - ], - "properties": { - "msg": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - }, - "sender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw1155/schema/approved_for_all_response.json b/packages/cw1155/schema/approved_for_all_response.json deleted file mode 100644 index 453f17b7c..000000000 --- a/packages/cw1155/schema/approved_for_all_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovedForAllResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/balance_response.json b/packages/cw1155/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/packages/cw1155/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/batch_balance_response.json b/packages/cw1155/schema/batch_balance_response.json deleted file mode 100644 index 39c8bd040..000000000 --- a/packages/cw1155/schema/batch_balance_response.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BatchBalanceResponse", - "type": "object", - "required": [ - "balances" - ], - "properties": { - "balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/cw1155_batch_receive_msg.json b/packages/cw1155/schema/cw1155_batch_receive_msg.json deleted file mode 100644 index 39820287c..000000000 --- a/packages/cw1155/schema/cw1155_batch_receive_msg.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155BatchReceiveMsg", - "description": "Cw1155BatchReceiveMsg should be de/serialized under `BatchReceive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "batch", - "msg", - "operator" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "operator": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/cw1155_execute_msg.json b/packages/cw1155/schema/cw1155_execute_msg.json deleted file mode 100644 index 41ebe3020..000000000 --- a/packages/cw1155/schema/cw1155_execute_msg.json +++ /dev/null @@ -1,383 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155ExecuteMsg", - "oneOf": [ - { - "description": "SendFrom is a base message to move tokens, if `env.sender` is the owner or has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "from", - "to", - "token_id", - "value" - ], - "properties": { - "from": { - "type": "string" - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchSendFrom is a base message to move multiple types of tokens in batch, if `env.sender` is the owner or has sufficient pre-approval.", - "type": "object", - "required": [ - "batch_send_from" - ], - "properties": { - "batch_send_from": { - "type": "object", - "required": [ - "batch", - "from", - "to" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": "string" - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "if `to` is not contract, `msg` should be `None`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Mint is a base message to mint tokens.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "to", - "token_id", - "value" - ], - "properties": { - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchMint is a base message to mint multiple types of tokens in batch.", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "batch", - "to" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to burn tokens.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "from", - "token_id", - "value" - ], - "properties": { - "from": { - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchBurn is a base message to burn multiple types of tokens in batch.", - "type": "object", - "required": [ - "batch_burn" - ], - "properties": { - "batch_burn": { - "type": "object", - "required": [ - "batch", - "from" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/cw1155_query_msg.json b/packages/cw1155/schema/cw1155_query_msg.json deleted file mode 100644 index fa4282450..000000000 --- a/packages/cw1155/schema/cw1155_query_msg.json +++ /dev/null @@ -1,211 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "owner", - "token_id" - ], - "properties": { - "owner": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns the current balance of the given address for a batch of tokens, 0 if unset. Return type: BatchBalanceResponse.", - "type": "object", - "required": [ - "batch_balance" - ], - "properties": { - "batch_balance": { - "type": "object", - "required": [ - "owner", - "token_ids" - ], - "properties": { - "owner": { - "type": "string" - }, - "token_ids": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "List all operators that can access all of the owner's tokens. Return type: ApprovedForAllResponse.", - "type": "object", - "required": [ - "approved_for_all" - ], - "properties": { - "approved_for_all": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Query approved status `owner` granted to `operator`. Return type: IsApprovedForAllResponse", - "type": "object", - "required": [ - "is_approved_for_all" - ], - "properties": { - "is_approved_for_all": { - "type": "object", - "required": [ - "operator", - "owner" - ], - "properties": { - "operator": { - "type": "string" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Query metadata of token Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Returns all tokens owned by the given address, [] if unset. Return type: TokensResponse.", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Requires pagination. Lists all token_ids controlled by the contract. Return type: TokensResponse.", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/packages/cw1155/schema/cw1155_receive_msg.json b/packages/cw1155/schema/cw1155_receive_msg.json deleted file mode 100644 index 1bf693cec..000000000 --- a/packages/cw1155/schema/cw1155_receive_msg.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155ReceiveMsg", - "description": "Cw1155ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "operator", - "token_id" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "from": { - "description": "The account that the token transfered from", - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "operator": { - "description": "The account that executed the send message", - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/is_approved_for_all_response.json b/packages/cw1155/schema/is_approved_for_all_response.json deleted file mode 100644 index e3af7a983..000000000 --- a/packages/cw1155/schema/is_approved_for_all_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsApprovedForAllResponse", - "type": "object", - "required": [ - "approved" - ], - "properties": { - "approved": { - "type": "boolean" - } - } -} diff --git a/packages/cw1155/schema/token_info_response.json b/packages/cw1155/schema/token_info_response.json deleted file mode 100644 index a94af98e3..000000000 --- a/packages/cw1155/schema/token_info_response.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "description": "Should be a url point to a json file", - "type": "string" - } - } -} diff --git a/packages/cw1155/schema/tokens_response.json b/packages/cw1155/schema/tokens_response.json deleted file mode 100644 index b8e3d75b5..000000000 --- a/packages/cw1155/schema/tokens_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_from` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/packages/cw20/schema/all_accounts_response.json b/packages/cw20/schema/all_accounts_response.json deleted file mode 100644 index cea50fba4..000000000 --- a/packages/cw20/schema/all_accounts_response.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAccountsResponse", - "type": "object", - "required": [ - "accounts" - ], - "properties": { - "accounts": { - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/packages/cw20/schema/all_allowances_response.json b/packages/cw20/schema/all_allowances_response.json deleted file mode 100644 index 6bb2291ce..000000000 --- a/packages/cw20/schema/all_allowances_response.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "allowance", - "expires", - "spender" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/allowance_response.json b/packages/cw20/schema/allowance_response.json deleted file mode 100644 index c4f98d6fc..000000000 --- a/packages/cw20/schema/allowance_response.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/balance_response.json b/packages/cw20/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/packages/cw20/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/cw20_execute_msg.json b/packages/cw20/schema/cw20_execute_msg.json deleted file mode 100644 index e4bc559cd..000000000 --- a/packages/cw20/schema/cw20_execute_msg.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw20ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"mintable\" extension. If authorized, creates amount new tokens and adds to the recipient balance.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"marketing\" extension. If authorized, updates marketing metadata. Setting None/null for any of these will leave it unchanged. Setting Some(\"\") will clear this field on the contract storage", - "type": "object", - "required": [ - "update_marketing" - ], - "properties": { - "update_marketing": { - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "type": [ - "string", - "null" - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "If set as the \"marketing\" role on the contract, upload a new URL, SVG, or PNG for the token", - "type": "object", - "required": [ - "upload_logo" - ], - "properties": { - "upload_logo": { - "$ref": "#/definitions/Logo" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/cw20_query_msg.json b/packages/cw20/schema/cw20_query_msg.json deleted file mode 100644 index 2dbeb2914..000000000 --- a/packages/cw20/schema/cw20_query_msg.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw20QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns metadata on the contract - name, decimals, supply, etc. Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset. Return type: AllowanceResponse.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"mintable\" extension. Returns who can mint and the hard cap on maximum tokens after minting. Return type: MinterResponse.", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Returns more metadata on the contract to display in the client: - description, logo, project url, etc. Return type: MarketingInfoResponse.", - "type": "object", - "required": [ - "marketing_info" - ], - "properties": { - "marketing_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Downloads the embedded logo data (if stored on chain). Errors if no logo data stored for this contract. Return type: DownloadLogoResponse.", - "type": "object", - "required": [ - "download_logo" - ], - "properties": { - "download_logo": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension (and \"allowances\") Returns all allowances this owner has approved. Supports pagination. Return type: AllAllowancesResponse.", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension Returns all accounts that have balances. Supports pagination. Return type: AllAccountsResponse.", - "type": "object", - "required": [ - "all_accounts" - ], - "properties": { - "all_accounts": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/packages/cw20/schema/cw20_receive_msg.json b/packages/cw20/schema/cw20_receive_msg.json deleted file mode 100644 index e06a24584..000000000 --- a/packages/cw20/schema/cw20_receive_msg.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw20ReceiveMsg", - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/download_logo_response.json b/packages/cw20/schema/download_logo_response.json deleted file mode 100644 index a4bac1f5c..000000000 --- a/packages/cw20/schema/download_logo_response.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DownloadLogoResponse", - "description": "When we download an embedded logo, we get this response type. We expect a SPA to be able to accept this info and display it.", - "type": "object", - "required": [ - "data", - "mime_type" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "mime_type": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/marketing_info_response.json b/packages/cw20/schema/marketing_info_response.json deleted file mode 100644 index 616d00de8..000000000 --- a/packages/cw20/schema/marketing_info_response.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MarketingInfoResponse", - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "logo": { - "description": "A link to the logo, or a comment there is an on-chain logo stored", - "anyOf": [ - { - "$ref": "#/definitions/LogoInfo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "LogoInfo": { - "description": "This is used to display logo info, provide a link or inform there is one that can be downloaded from the blockchain itself", - "oneOf": [ - { - "type": "string", - "enum": [ - "embedded" - ] - }, - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw20/schema/minter_response.json b/packages/cw20/schema/minter_response.json deleted file mode 100644 index a05f8fd58..000000000 --- a/packages/cw20/schema/minter_response.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw20/schema/token_info_response.json b/packages/cw20/schema/token_info_response.json deleted file mode 100644 index 9920c841f..000000000 --- a/packages/cw20/schema/token_info_response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/cw3/schema/execute_msg.json b/packages/cw3/schema/execute_msg.json deleted file mode 100644 index 896d2c86f..000000000 --- a/packages/cw3/schema/execute_msg.json +++ /dev/null @@ -1,495 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "propose" - ], - "properties": { - "propose": { - "type": "object", - "required": [ - "description", - "msgs", - "title" - ], - "properties": { - "description": { - "type": "string" - }, - "earliest": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "latest": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - }, - "title": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/Vote" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "close" - ], - "properties": { - "close": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Vote": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "veto" - ] - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw3/schema/proposal_list_response.json b/packages/cw3/schema/proposal_list_response.json deleted file mode 100644 index c14db0eb4..000000000 --- a/packages/cw3/schema/proposal_list_response.json +++ /dev/null @@ -1,527 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ProposalListResponse", - "type": "object", - "required": [ - "proposals" - ], - "properties": { - "proposals": { - "type": "array", - "items": { - "$ref": "#/definitions/ProposalResponse_for_Empty" - } - } - }, - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "ProposalResponse_for_Empty": { - "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", - "type": "object", - "required": [ - "description", - "expires", - "id", - "msgs", - "status", - "threshold", - "title" - ], - "properties": { - "description": { - "type": "string" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - }, - "status": { - "$ref": "#/definitions/Status" - }, - "threshold": { - "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", - "allOf": [ - { - "$ref": "#/definitions/ThresholdResponse" - } - ] - }, - "title": { - "type": "string" - } - } - }, - "Status": { - "type": "string", - "enum": [ - "pending", - "open", - "rejected", - "passed", - "executed" - ] - }, - "ThresholdResponse": { - "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", - "oneOf": [ - { - "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", - "type": "object", - "required": [ - "absolute_count" - ], - "properties": { - "absolute_count": { - "type": "object", - "required": [ - "total_weight", - "weight" - ], - "properties": { - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", - "type": "object", - "required": [ - "absolute_percentage" - ], - "properties": { - "absolute_percentage": { - "type": "object", - "required": [ - "percentage", - "total_weight" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", - "type": "object", - "required": [ - "threshold_quorum" - ], - "properties": { - "threshold_quorum": { - "type": "object", - "required": [ - "quorum", - "threshold", - "total_weight" - ], - "properties": { - "quorum": { - "$ref": "#/definitions/Decimal" - }, - "threshold": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw3/schema/proposal_response.json b/packages/cw3/schema/proposal_response.json deleted file mode 100644 index 42acdea03..000000000 --- a/packages/cw3/schema/proposal_response.json +++ /dev/null @@ -1,513 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ProposalResponse", - "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", - "type": "object", - "required": [ - "description", - "expires", - "id", - "msgs", - "status", - "threshold", - "title" - ], - "properties": { - "description": { - "type": "string" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - }, - "status": { - "$ref": "#/definitions/Status" - }, - "threshold": { - "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", - "allOf": [ - { - "$ref": "#/definitions/ThresholdResponse" - } - ] - }, - "title": { - "type": "string" - } - }, - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Status": { - "type": "string", - "enum": [ - "pending", - "open", - "rejected", - "passed", - "executed" - ] - }, - "ThresholdResponse": { - "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", - "oneOf": [ - { - "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", - "type": "object", - "required": [ - "absolute_count" - ], - "properties": { - "absolute_count": { - "type": "object", - "required": [ - "total_weight", - "weight" - ], - "properties": { - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", - "type": "object", - "required": [ - "absolute_percentage" - ], - "properties": { - "absolute_percentage": { - "type": "object", - "required": [ - "percentage", - "total_weight" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", - "type": "object", - "required": [ - "threshold_quorum" - ], - "properties": { - "threshold_quorum": { - "type": "object", - "required": [ - "quorum", - "threshold", - "total_weight" - ], - "properties": { - "quorum": { - "$ref": "#/definitions/Decimal" - }, - "threshold": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw3/schema/query_msg.json b/packages/cw3/schema/query_msg.json deleted file mode 100644 index 7e1dcaa65..000000000 --- a/packages/cw3/schema/query_msg.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the threshold rules that would be used for a new proposal that was opened right now. The threshold rules do not change often, but the `total_weight` in the response may easily differ from that used in previously opened proposals. Returns ThresholdResponse.", - "type": "object", - "required": [ - "threshold" - ], - "properties": { - "threshold": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns details of the proposal state. Returns ProposalResponse.", - "type": "object", - "required": [ - "proposal" - ], - "properties": { - "proposal": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Iterate over details of all proposals from oldest to newest. Returns ProposalListResponse", - "type": "object", - "required": [ - "list_proposals" - ], - "properties": { - "list_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Iterate reverse over details of all proposals, this is useful to easily query only the most recent proposals (to get updates). Returns ProposalListResponse", - "type": "object", - "required": [ - "reverse_proposals" - ], - "properties": { - "reverse_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_before": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Query the vote made by the given voter on `proposal_id`. This should return an error if there is no such proposal. It will return a None value if the proposal exists but the voter did not vote. Returns VoteResponse", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "voter" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "voter": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Iterate (with pagination) over all votes for this proposal. The ordering is arbitrary, unlikely to be sorted by address. But ordering is consistent and pagination from the end of each page will cover all votes for the proposal. Returns VoteListResponse", - "type": "object", - "required": [ - "list_votes" - ], - "properties": { - "list_votes": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Voter extension: Returns VoterResponse", - "type": "object", - "required": [ - "voter" - ], - "properties": { - "voter": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "ListVoters extension: Returns VoterListResponse", - "type": "object", - "required": [ - "list_voters" - ], - "properties": { - "list_voters": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/packages/cw3/schema/threshold_response.json b/packages/cw3/schema/threshold_response.json deleted file mode 100644 index c36b4a566..000000000 --- a/packages/cw3/schema/threshold_response.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ThresholdResponse", - "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", - "oneOf": [ - { - "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", - "type": "object", - "required": [ - "absolute_count" - ], - "properties": { - "absolute_count": { - "type": "object", - "required": [ - "total_weight", - "weight" - ], - "properties": { - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", - "type": "object", - "required": [ - "absolute_percentage" - ], - "properties": { - "absolute_percentage": { - "type": "object", - "required": [ - "percentage", - "total_weight" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", - "type": "object", - "required": [ - "threshold_quorum" - ], - "properties": { - "threshold_quorum": { - "type": "object", - "required": [ - "quorum", - "threshold", - "total_weight" - ], - "properties": { - "quorum": { - "$ref": "#/definitions/Decimal" - }, - "threshold": { - "$ref": "#/definitions/Decimal" - }, - "total_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - } - } -} diff --git a/packages/cw3/schema/vote_list_response.json b/packages/cw3/schema/vote_list_response.json deleted file mode 100644 index d0c22b6ba..000000000 --- a/packages/cw3/schema/vote_list_response.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VoteListResponse", - "type": "object", - "required": [ - "votes" - ], - "properties": { - "votes": { - "type": "array", - "items": { - "$ref": "#/definitions/VoteInfo" - } - } - }, - "definitions": { - "Vote": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "veto" - ] - }, - "VoteInfo": { - "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", - "type": "object", - "required": [ - "vote", - "voter", - "weight" - ], - "properties": { - "vote": { - "$ref": "#/definitions/Vote" - }, - "voter": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/packages/cw3/schema/vote_response.json b/packages/cw3/schema/vote_response.json deleted file mode 100644 index eaf97cfee..000000000 --- a/packages/cw3/schema/vote_response.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VoteResponse", - "type": "object", - "properties": { - "vote": { - "anyOf": [ - { - "$ref": "#/definitions/VoteInfo" - }, - { - "type": "null" - } - ] - } - }, - "definitions": { - "Vote": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "veto" - ] - }, - "VoteInfo": { - "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", - "type": "object", - "required": [ - "vote", - "voter", - "weight" - ], - "properties": { - "vote": { - "$ref": "#/definitions/Vote" - }, - "voter": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/packages/cw3/schema/voter_detail.json b/packages/cw3/schema/voter_detail.json deleted file mode 100644 index b9543b60a..000000000 --- a/packages/cw3/schema/voter_detail.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VoterDetail", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/packages/cw3/schema/voter_list_response.json b/packages/cw3/schema/voter_list_response.json deleted file mode 100644 index 17535bdc9..000000000 --- a/packages/cw3/schema/voter_list_response.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VoterListResponse", - "type": "object", - "required": [ - "voters" - ], - "properties": { - "voters": { - "type": "array", - "items": { - "$ref": "#/definitions/VoterDetail" - } - } - }, - "definitions": { - "VoterDetail": { - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/packages/cw3/schema/voter_response.json b/packages/cw3/schema/voter_response.json deleted file mode 100644 index 6fefcfb6b..000000000 --- a/packages/cw3/schema/voter_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VoterResponse", - "type": "object", - "properties": { - "weight": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/packages/cw4/schema/admin_response.json b/packages/cw4/schema/admin_response.json deleted file mode 100644 index 82bf62a3a..000000000 --- a/packages/cw4/schema/admin_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminResponse", - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } -} diff --git a/packages/cw4/schema/cw4_execute_msg.json b/packages/cw4/schema/cw4_execute_msg.json deleted file mode 100644 index 9a3b3bb63..000000000 --- a/packages/cw4/schema/cw4_execute_msg.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw4ExecuteMsg", - "oneOf": [ - { - "description": "Change the admin", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Add a new hook to be informed of all membership changes. Must be called by Admin", - "type": "object", - "required": [ - "add_hook" - ], - "properties": { - "add_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove a hook. Must be called by Admin", - "type": "object", - "required": [ - "remove_hook" - ], - "properties": { - "remove_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/packages/cw4/schema/cw4_query_msg.json b/packages/cw4/schema/cw4_query_msg.json deleted file mode 100644 index f31ac791a..000000000 --- a/packages/cw4/schema/cw4_query_msg.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw4QueryMsg", - "oneOf": [ - { - "description": "Return AdminResponse", - "type": "object", - "required": [ - "admin" - ], - "properties": { - "admin": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Return TotalWeightResponse", - "type": "object", - "required": [ - "total_weight" - ], - "properties": { - "total_weight": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns MembersListResponse", - "type": "object", - "required": [ - "list_members" - ], - "properties": { - "list_members": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns MemberResponse", - "type": "object", - "required": [ - "member" - ], - "properties": { - "member": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - }, - "at_height": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Shows all registered hooks. Returns HooksResponse.", - "type": "object", - "required": [ - "hooks" - ], - "properties": { - "hooks": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/packages/cw4/schema/member_changed_hook_msg.json b/packages/cw4/schema/member_changed_hook_msg.json deleted file mode 100644 index 983f51d12..000000000 --- a/packages/cw4/schema/member_changed_hook_msg.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberChangedHookMsg", - "description": "MemberChangedHookMsg should be de/serialized under `MemberChangedHook()` variant in a ExecuteMsg. This contains a list of all diffs on the given transaction.", - "type": "object", - "required": [ - "diffs" - ], - "properties": { - "diffs": { - "type": "array", - "items": { - "$ref": "#/definitions/MemberDiff" - } - } - }, - "definitions": { - "MemberDiff": { - "description": "MemberDiff shows the old and new states for a given cw4 member They cannot both be None. old = None, new = Some -> Insert old = Some, new = Some -> Update old = Some, new = None -> Delete", - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - }, - "new": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "old": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/packages/cw4/schema/member_list_response.json b/packages/cw4/schema/member_list_response.json deleted file mode 100644 index ae09f9bba..000000000 --- a/packages/cw4/schema/member_list_response.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberListResponse", - "type": "object", - "required": [ - "members" - ], - "properties": { - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/Member" - } - } - }, - "definitions": { - "Member": { - "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/packages/cw4/schema/member_response.json b/packages/cw4/schema/member_response.json deleted file mode 100644 index c78ed8623..000000000 --- a/packages/cw4/schema/member_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberResponse", - "type": "object", - "properties": { - "weight": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/packages/cw4/schema/total_weight_response.json b/packages/cw4/schema/total_weight_response.json deleted file mode 100644 index 61db7a998..000000000 --- a/packages/cw4/schema/total_weight_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalWeightResponse", - "type": "object", - "required": [ - "weight" - ], - "properties": { - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} From 2f08eb738e65306aefc275653e1367a435177a0d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 16:08:43 +0100 Subject: [PATCH 072/631] Remove contracts schemas from repo --- .../schema/admin_list_response.json | 20 - .../schema/all_allowances_response.json | 120 --- contracts/cw1-subkeys/schema/allowance.json | 102 --- contracts/cw1-subkeys/schema/execute_msg.json | 700 ------------------ .../cw1-subkeys/schema/instantiate_msg.json | 20 - contracts/cw1-subkeys/schema/query_msg.json | 602 --------------- .../schema/admin_list_response.json | 20 - .../cw1-whitelist-ng/schema/cw1_exec_msg.json | 488 ------------ .../schema/cw1_query_msg.json | 489 ------------ .../schema/instantiate_msg.json | 20 - .../schema/whitelist_exec_msg.json | 43 -- .../schema/whitelist_query_msg.json | 19 - .../schema/admin_list_response.json | 20 - .../cw1-whitelist/schema/execute_msg.json | 525 ------------- .../cw1-whitelist/schema/instantiate_msg.json | 20 - contracts/cw1-whitelist/schema/query_msg.json | 502 ------------- .../schema/approved_for_all_response.json | 97 --- .../cw1155-base/schema/balance_response.json | 19 - .../schema/batch_balance_response.json | 22 - .../schema/cw1155_batch_receive_msg.json | 51 -- .../schema/cw1155_execute_msg.json | 383 ---------- .../cw1155-base/schema/cw1155_query_msg.json | 211 ------ .../schema/cw1155_receive_msg.json | 44 -- .../cw1155-base/schema/instantiate_msg.json | 14 - .../schema/is_approved_for_all_response.json | 13 - .../schema/token_info_response.json | 14 - .../cw1155-base/schema/tokens_response.json | 17 - .../schema/details_response.json | 172 ----- .../cw20-atomic-swap/schema/execute_msg.json | 197 ----- .../schema/instantiate_msg.json | 5 - .../schema/list_response.json | 17 - .../cw20-atomic-swap/schema/query_msg.json | 56 -- .../schema/all_accounts_response.json | 16 - .../schema/all_allowances_response.json | 99 --- .../cw20-base/schema/allowance_response.json | 81 -- .../cw20-base/schema/balance_response.json | 19 - .../cw20-base/schema/cw20_execute_msg.json | 442 ----------- .../cw20-base/schema/instantiate_msg.json | 192 ----- contracts/cw20-base/schema/query_msg.json | 168 ----- .../cw20-base/schema/token_info_response.json | 33 - .../schema/allowance_response.json | 81 -- .../cw20-bonding/schema/balance_response.json | 19 - .../schema/curve_info_response.json | 35 - .../cw20-bonding/schema/execute_msg.json | 319 -------- .../cw20-bonding/schema/instantiate_msg.json | 138 ---- contracts/cw20-bonding/schema/query_msg.json | 78 -- .../schema/token_info_response.json | 33 - .../cw20-escrow/schema/details_response.json | 107 --- contracts/cw20-escrow/schema/execute_msg.json | 176 ----- .../cw20-escrow/schema/instantiate_msg.json | 5 - .../cw20-escrow/schema/list_response.json | 17 - contracts/cw20-escrow/schema/query_msg.json | 40 - contracts/cw20-escrow/schema/receive_msg.json | 91 --- .../cw20-ics20/schema/channel_response.json | 139 ---- contracts/cw20-ics20/schema/execute_msg.json | 89 --- contracts/cw20-ics20/schema/init_msg.json | 16 - .../schema/list_channels_response.json | 59 -- .../cw20-ics20/schema/port_response.json | 13 - contracts/cw20-ics20/schema/query_msg.json | 53 -- contracts/cw20-ics20/schema/transfer_msg.json | 29 - .../schema/config_response.json | 19 - .../schema/execute_msg.json | 89 --- .../schema/instantiate_msg.json | 20 - .../schema/is_claimed_response.json | 13 - .../schema/latest_stage_response.json | 15 - .../schema/merkle_root_response.json | 20 - .../cw20-merkle-airdrop/schema/query_msg.json | 78 -- .../schema/allowance_response.json | 81 -- .../cw20-staking/schema/balance_response.json | 19 - .../cw20-staking/schema/claims_response.json | 95 --- .../cw20-staking/schema/execute_msg.json | 379 ---------- .../cw20-staking/schema/instantiate_msg.json | 102 --- .../schema/investment_response.json | 74 -- contracts/cw20-staking/schema/query_msg.json | 99 --- .../schema/token_info_response.json | 33 - .../schema/execute_msg.json | 642 ---------------- .../schema/instantiate_msg.json | 79 -- .../cw3-fixed-multisig/schema/query_msg.json | 218 ------ .../cw3-flex-multisig/schema/execute_msg.json | 698 ----------------- .../schema/instantiate_msg.json | 135 ---- .../cw3-flex-multisig/schema/query_msg.json | 218 ------ .../cw4-group/schema/admin_response.json | 13 - contracts/cw4-group/schema/execute_msg.json | 120 --- .../cw4-group/schema/instantiate_msg.json | 43 -- .../schema/member_list_response.json | 36 - .../cw4-group/schema/member_response.json | 15 - contracts/cw4-group/schema/query_msg.json | 103 --- .../schema/total_weight_response.json | 15 - .../cw4-stake/schema/admin_response.json | 13 - .../cw4-stake/schema/claims_response.json | 95 --- contracts/cw4-stake/schema/execute_msg.json | 159 ---- .../cw4-stake/schema/instantiate_msg.json | 108 --- .../schema/member_list_response.json | 36 - .../cw4-stake/schema/member_response.json | 15 - contracts/cw4-stake/schema/query_msg.json | 144 ---- contracts/cw4-stake/schema/receive_msg.json | 19 - .../cw4-stake/schema/staked_response.json | 55 -- .../schema/total_weight_response.json | 15 - 98 files changed, 11759 deletions(-) delete mode 100644 contracts/cw1-subkeys/schema/admin_list_response.json delete mode 100644 contracts/cw1-subkeys/schema/all_allowances_response.json delete mode 100644 contracts/cw1-subkeys/schema/allowance.json delete mode 100644 contracts/cw1-subkeys/schema/execute_msg.json delete mode 100644 contracts/cw1-subkeys/schema/instantiate_msg.json delete mode 100644 contracts/cw1-subkeys/schema/query_msg.json delete mode 100644 contracts/cw1-whitelist-ng/schema/admin_list_response.json delete mode 100644 contracts/cw1-whitelist-ng/schema/cw1_exec_msg.json delete mode 100644 contracts/cw1-whitelist-ng/schema/cw1_query_msg.json delete mode 100644 contracts/cw1-whitelist-ng/schema/instantiate_msg.json delete mode 100644 contracts/cw1-whitelist-ng/schema/whitelist_exec_msg.json delete mode 100644 contracts/cw1-whitelist-ng/schema/whitelist_query_msg.json delete mode 100644 contracts/cw1-whitelist/schema/admin_list_response.json delete mode 100644 contracts/cw1-whitelist/schema/execute_msg.json delete mode 100644 contracts/cw1-whitelist/schema/instantiate_msg.json delete mode 100644 contracts/cw1-whitelist/schema/query_msg.json delete mode 100644 contracts/cw1155-base/schema/approved_for_all_response.json delete mode 100644 contracts/cw1155-base/schema/balance_response.json delete mode 100644 contracts/cw1155-base/schema/batch_balance_response.json delete mode 100644 contracts/cw1155-base/schema/cw1155_batch_receive_msg.json delete mode 100644 contracts/cw1155-base/schema/cw1155_execute_msg.json delete mode 100644 contracts/cw1155-base/schema/cw1155_query_msg.json delete mode 100644 contracts/cw1155-base/schema/cw1155_receive_msg.json delete mode 100644 contracts/cw1155-base/schema/instantiate_msg.json delete mode 100644 contracts/cw1155-base/schema/is_approved_for_all_response.json delete mode 100644 contracts/cw1155-base/schema/token_info_response.json delete mode 100644 contracts/cw1155-base/schema/tokens_response.json delete mode 100644 contracts/cw20-atomic-swap/schema/details_response.json delete mode 100644 contracts/cw20-atomic-swap/schema/execute_msg.json delete mode 100644 contracts/cw20-atomic-swap/schema/instantiate_msg.json delete mode 100644 contracts/cw20-atomic-swap/schema/list_response.json delete mode 100644 contracts/cw20-atomic-swap/schema/query_msg.json delete mode 100644 contracts/cw20-base/schema/all_accounts_response.json delete mode 100644 contracts/cw20-base/schema/all_allowances_response.json delete mode 100644 contracts/cw20-base/schema/allowance_response.json delete mode 100644 contracts/cw20-base/schema/balance_response.json delete mode 100644 contracts/cw20-base/schema/cw20_execute_msg.json delete mode 100644 contracts/cw20-base/schema/instantiate_msg.json delete mode 100644 contracts/cw20-base/schema/query_msg.json delete mode 100644 contracts/cw20-base/schema/token_info_response.json delete mode 100644 contracts/cw20-bonding/schema/allowance_response.json delete mode 100644 contracts/cw20-bonding/schema/balance_response.json delete mode 100644 contracts/cw20-bonding/schema/curve_info_response.json delete mode 100644 contracts/cw20-bonding/schema/execute_msg.json delete mode 100644 contracts/cw20-bonding/schema/instantiate_msg.json delete mode 100644 contracts/cw20-bonding/schema/query_msg.json delete mode 100644 contracts/cw20-bonding/schema/token_info_response.json delete mode 100644 contracts/cw20-escrow/schema/details_response.json delete mode 100644 contracts/cw20-escrow/schema/execute_msg.json delete mode 100644 contracts/cw20-escrow/schema/instantiate_msg.json delete mode 100644 contracts/cw20-escrow/schema/list_response.json delete mode 100644 contracts/cw20-escrow/schema/query_msg.json delete mode 100644 contracts/cw20-escrow/schema/receive_msg.json delete mode 100644 contracts/cw20-ics20/schema/channel_response.json delete mode 100644 contracts/cw20-ics20/schema/execute_msg.json delete mode 100644 contracts/cw20-ics20/schema/init_msg.json delete mode 100644 contracts/cw20-ics20/schema/list_channels_response.json delete mode 100644 contracts/cw20-ics20/schema/port_response.json delete mode 100644 contracts/cw20-ics20/schema/query_msg.json delete mode 100644 contracts/cw20-ics20/schema/transfer_msg.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/config_response.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/execute_msg.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/instantiate_msg.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/is_claimed_response.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/latest_stage_response.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/merkle_root_response.json delete mode 100644 contracts/cw20-merkle-airdrop/schema/query_msg.json delete mode 100644 contracts/cw20-staking/schema/allowance_response.json delete mode 100644 contracts/cw20-staking/schema/balance_response.json delete mode 100644 contracts/cw20-staking/schema/claims_response.json delete mode 100644 contracts/cw20-staking/schema/execute_msg.json delete mode 100644 contracts/cw20-staking/schema/instantiate_msg.json delete mode 100644 contracts/cw20-staking/schema/investment_response.json delete mode 100644 contracts/cw20-staking/schema/query_msg.json delete mode 100644 contracts/cw20-staking/schema/token_info_response.json delete mode 100644 contracts/cw3-fixed-multisig/schema/execute_msg.json delete mode 100644 contracts/cw3-fixed-multisig/schema/instantiate_msg.json delete mode 100644 contracts/cw3-fixed-multisig/schema/query_msg.json delete mode 100644 contracts/cw3-flex-multisig/schema/execute_msg.json delete mode 100644 contracts/cw3-flex-multisig/schema/instantiate_msg.json delete mode 100644 contracts/cw3-flex-multisig/schema/query_msg.json delete mode 100644 contracts/cw4-group/schema/admin_response.json delete mode 100644 contracts/cw4-group/schema/execute_msg.json delete mode 100644 contracts/cw4-group/schema/instantiate_msg.json delete mode 100644 contracts/cw4-group/schema/member_list_response.json delete mode 100644 contracts/cw4-group/schema/member_response.json delete mode 100644 contracts/cw4-group/schema/query_msg.json delete mode 100644 contracts/cw4-group/schema/total_weight_response.json delete mode 100644 contracts/cw4-stake/schema/admin_response.json delete mode 100644 contracts/cw4-stake/schema/claims_response.json delete mode 100644 contracts/cw4-stake/schema/execute_msg.json delete mode 100644 contracts/cw4-stake/schema/instantiate_msg.json delete mode 100644 contracts/cw4-stake/schema/member_list_response.json delete mode 100644 contracts/cw4-stake/schema/member_response.json delete mode 100644 contracts/cw4-stake/schema/query_msg.json delete mode 100644 contracts/cw4-stake/schema/receive_msg.json delete mode 100644 contracts/cw4-stake/schema/staked_response.json delete mode 100644 contracts/cw4-stake/schema/total_weight_response.json diff --git a/contracts/cw1-subkeys/schema/admin_list_response.json b/contracts/cw1-subkeys/schema/admin_list_response.json deleted file mode 100644 index bc20467c3..000000000 --- a/contracts/cw1-subkeys/schema/admin_list_response.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminListResponse", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-subkeys/schema/all_allowances_response.json b/contracts/cw1-subkeys/schema/all_allowances_response.json deleted file mode 100644 index 287b75024..000000000 --- a/contracts/cw1-subkeys/schema/all_allowances_response.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "balance", - "expires", - "spender" - ], - "properties": { - "balance": { - "$ref": "#/definitions/NativeBalance" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - } - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "NativeBalance": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1-subkeys/schema/allowance.json b/contracts/cw1-subkeys/schema/allowance.json deleted file mode 100644 index 2a8fb26b8..000000000 --- a/contracts/cw1-subkeys/schema/allowance.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Allowance", - "type": "object", - "required": [ - "balance", - "expires" - ], - "properties": { - "balance": { - "$ref": "#/definitions/NativeBalance" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "NativeBalance": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1-subkeys/schema/execute_msg.json b/contracts/cw1-subkeys/schema/execute_msg.json deleted file mode 100644 index d1f887237..000000000 --- a/contracts/cw1-subkeys/schema/execute_msg.json +++ /dev/null @@ -1,700 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Execute requests the contract to re-dispatch all these messages with the contract's address as sender. Every implementation has it's own logic to determine in", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "msgs" - ], - "properties": { - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Freeze will make a mutable contract immutable, must be called by an admin", - "type": "object", - "required": [ - "freeze" - ], - "properties": { - "freeze": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "UpdateAdmins will change the admin set of the contract, must be called by an existing admin, and only works if the contract is mutable", - "type": "object", - "required": [ - "update_admins" - ], - "properties": { - "update_admins": { - "type": "object", - "required": [ - "admins" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Add an allowance to a given subkey (subkey must not be admin)", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Decreases an allowance for a given subkey (subkey must not be admin)", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permissions" - ], - "properties": { - "set_permissions": { - "type": "object", - "required": [ - "permissions", - "spender" - ], - "properties": { - "permissions": { - "$ref": "#/definitions/Permissions" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Permissions": { - "type": "object", - "required": [ - "delegate", - "redelegate", - "undelegate", - "withdraw" - ], - "properties": { - "delegate": { - "type": "boolean" - }, - "redelegate": { - "type": "boolean" - }, - "undelegate": { - "type": "boolean" - }, - "withdraw": { - "type": "boolean" - } - } - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1-subkeys/schema/instantiate_msg.json b/contracts/cw1-subkeys/schema/instantiate_msg.json deleted file mode 100644 index fdcd684aa..000000000 --- a/contracts/cw1-subkeys/schema/instantiate_msg.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-subkeys/schema/query_msg.json b/contracts/cw1-subkeys/schema/query_msg.json deleted file mode 100644 index 1fc41ead7..000000000 --- a/contracts/cw1-subkeys/schema/query_msg.json +++ /dev/null @@ -1,602 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Shows all admins and whether or not it is mutable Returns cw1-whitelist::AdminListResponse", - "type": "object", - "required": [ - "admin_list" - ], - "properties": { - "admin_list": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Get the current allowance for the given subkey (how much it can spend) Returns crate::state::Allowance", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "spender" - ], - "properties": { - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Get the current permissions for the given subkey (how much it can spend) Returns PermissionsInfo", - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "spender" - ], - "properties": { - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.", - "type": "object", - "required": [ - "can_execute" - ], - "properties": { - "can_execute": { - "type": "object", - "required": [ - "msg", - "sender" - ], - "properties": { - "msg": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - }, - "sender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Gets all Allowances for this contract Returns AllAllowancesResponse", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Gets all Permissions for this contract Returns AllPermissionsResponse", - "type": "object", - "required": [ - "all_permissions" - ], - "properties": { - "all_permissions": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1-whitelist-ng/schema/admin_list_response.json b/contracts/cw1-whitelist-ng/schema/admin_list_response.json deleted file mode 100644 index bc20467c3..000000000 --- a/contracts/cw1-whitelist-ng/schema/admin_list_response.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminListResponse", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-whitelist-ng/schema/cw1_exec_msg.json b/contracts/cw1-whitelist-ng/schema/cw1_exec_msg.json deleted file mode 100644 index 0eed149ec..000000000 --- a/contracts/cw1-whitelist-ng/schema/cw1_exec_msg.json +++ /dev/null @@ -1,488 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1ExecMsg", - "oneOf": [ - { - "description": "Execute requests the contract to re-dispatch all these messages with the contract's address as sender. Every implementation has it's own logic to determine in", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "msgs" - ], - "properties": { - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1-whitelist-ng/schema/cw1_query_msg.json b/contracts/cw1-whitelist-ng/schema/cw1_query_msg.json deleted file mode 100644 index 7783a494a..000000000 --- a/contracts/cw1-whitelist-ng/schema/cw1_query_msg.json +++ /dev/null @@ -1,489 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1QueryMsg", - "oneOf": [ - { - "description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.", - "type": "object", - "required": [ - "can_execute" - ], - "properties": { - "can_execute": { - "type": "object", - "required": [ - "msg", - "sender" - ], - "properties": { - "msg": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - }, - "sender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1-whitelist-ng/schema/instantiate_msg.json b/contracts/cw1-whitelist-ng/schema/instantiate_msg.json deleted file mode 100644 index fdcd684aa..000000000 --- a/contracts/cw1-whitelist-ng/schema/instantiate_msg.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-whitelist-ng/schema/whitelist_exec_msg.json b/contracts/cw1-whitelist-ng/schema/whitelist_exec_msg.json deleted file mode 100644 index 0ac87ee51..000000000 --- a/contracts/cw1-whitelist-ng/schema/whitelist_exec_msg.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WhitelistExecMsg", - "oneOf": [ - { - "description": "Freeze will make a mutable contract immutable, must be called by an admin", - "type": "object", - "required": [ - "freeze" - ], - "properties": { - "freeze": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "UpdateAdmins will change the admin set of the contract, must be called by an existing admin, and only works if the contract is mutable", - "type": "object", - "required": [ - "update_admins" - ], - "properties": { - "update_admins": { - "type": "object", - "required": [ - "admins" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw1-whitelist-ng/schema/whitelist_query_msg.json b/contracts/cw1-whitelist-ng/schema/whitelist_query_msg.json deleted file mode 100644 index b5d8ed25f..000000000 --- a/contracts/cw1-whitelist-ng/schema/whitelist_query_msg.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WhitelistQueryMsg", - "oneOf": [ - { - "description": "Shows all admins and whether or not it is mutable", - "type": "object", - "required": [ - "admin_list" - ], - "properties": { - "admin_list": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw1-whitelist/schema/admin_list_response.json b/contracts/cw1-whitelist/schema/admin_list_response.json deleted file mode 100644 index bc20467c3..000000000 --- a/contracts/cw1-whitelist/schema/admin_list_response.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminListResponse", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-whitelist/schema/execute_msg.json b/contracts/cw1-whitelist/schema/execute_msg.json deleted file mode 100644 index 50ca31e12..000000000 --- a/contracts/cw1-whitelist/schema/execute_msg.json +++ /dev/null @@ -1,525 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Execute requests the contract to re-dispatch all these messages with the contract's address as sender. Every implementation has it's own logic to determine in", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "msgs" - ], - "properties": { - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Freeze will make a mutable contract immutable, must be called by an admin", - "type": "object", - "required": [ - "freeze" - ], - "properties": { - "freeze": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "UpdateAdmins will change the admin set of the contract, must be called by an existing admin, and only works if the contract is mutable", - "type": "object", - "required": [ - "update_admins" - ], - "properties": { - "update_admins": { - "type": "object", - "required": [ - "admins" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1-whitelist/schema/instantiate_msg.json b/contracts/cw1-whitelist/schema/instantiate_msg.json deleted file mode 100644 index fdcd684aa..000000000 --- a/contracts/cw1-whitelist/schema/instantiate_msg.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "admins", - "mutable" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "mutable": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1-whitelist/schema/query_msg.json b/contracts/cw1-whitelist/schema/query_msg.json deleted file mode 100644 index 7ce7782ec..000000000 --- a/contracts/cw1-whitelist/schema/query_msg.json +++ /dev/null @@ -1,502 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Shows all admins and whether or not it is mutable", - "type": "object", - "required": [ - "admin_list" - ], - "properties": { - "admin_list": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.", - "type": "object", - "required": [ - "can_execute" - ], - "properties": { - "can_execute": { - "type": "object", - "required": [ - "msg", - "sender" - ], - "properties": { - "msg": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - }, - "sender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw1155-base/schema/approved_for_all_response.json b/contracts/cw1155-base/schema/approved_for_all_response.json deleted file mode 100644 index 453f17b7c..000000000 --- a/contracts/cw1155-base/schema/approved_for_all_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovedForAllResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/balance_response.json b/contracts/cw1155-base/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/contracts/cw1155-base/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/batch_balance_response.json b/contracts/cw1155-base/schema/batch_balance_response.json deleted file mode 100644 index 39c8bd040..000000000 --- a/contracts/cw1155-base/schema/batch_balance_response.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BatchBalanceResponse", - "type": "object", - "required": [ - "balances" - ], - "properties": { - "balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/cw1155_batch_receive_msg.json b/contracts/cw1155-base/schema/cw1155_batch_receive_msg.json deleted file mode 100644 index 39820287c..000000000 --- a/contracts/cw1155-base/schema/cw1155_batch_receive_msg.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155BatchReceiveMsg", - "description": "Cw1155BatchReceiveMsg should be de/serialized under `BatchReceive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "batch", - "msg", - "operator" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "operator": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/cw1155_execute_msg.json b/contracts/cw1155-base/schema/cw1155_execute_msg.json deleted file mode 100644 index 41ebe3020..000000000 --- a/contracts/cw1155-base/schema/cw1155_execute_msg.json +++ /dev/null @@ -1,383 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155ExecuteMsg", - "oneOf": [ - { - "description": "SendFrom is a base message to move tokens, if `env.sender` is the owner or has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "from", - "to", - "token_id", - "value" - ], - "properties": { - "from": { - "type": "string" - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchSendFrom is a base message to move multiple types of tokens in batch, if `env.sender` is the owner or has sufficient pre-approval.", - "type": "object", - "required": [ - "batch_send_from" - ], - "properties": { - "batch_send_from": { - "type": "object", - "required": [ - "batch", - "from", - "to" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": "string" - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "if `to` is not contract, `msg` should be `None`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Mint is a base message to mint tokens.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "to", - "token_id", - "value" - ], - "properties": { - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchMint is a base message to mint multiple types of tokens in batch.", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "batch", - "to" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "msg": { - "description": "`None` means don't call the receiver interface", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "to": { - "description": "If `to` is not contract, `msg` should be `None`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to burn tokens.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "from", - "token_id", - "value" - ], - "properties": { - "from": { - "type": "string" - }, - "token_id": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "BatchBurn is a base message to burn multiple types of tokens in batch.", - "type": "object", - "required": [ - "batch_burn" - ], - "properties": { - "batch_burn": { - "type": "object", - "required": [ - "batch", - "from" - ], - "properties": { - "batch": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "from": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/cw1155_query_msg.json b/contracts/cw1155-base/schema/cw1155_query_msg.json deleted file mode 100644 index fa4282450..000000000 --- a/contracts/cw1155-base/schema/cw1155_query_msg.json +++ /dev/null @@ -1,211 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "owner", - "token_id" - ], - "properties": { - "owner": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns the current balance of the given address for a batch of tokens, 0 if unset. Return type: BatchBalanceResponse.", - "type": "object", - "required": [ - "batch_balance" - ], - "properties": { - "batch_balance": { - "type": "object", - "required": [ - "owner", - "token_ids" - ], - "properties": { - "owner": { - "type": "string" - }, - "token_ids": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "List all operators that can access all of the owner's tokens. Return type: ApprovedForAllResponse.", - "type": "object", - "required": [ - "approved_for_all" - ], - "properties": { - "approved_for_all": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Query approved status `owner` granted to `operator`. Return type: IsApprovedForAllResponse", - "type": "object", - "required": [ - "is_approved_for_all" - ], - "properties": { - "is_approved_for_all": { - "type": "object", - "required": [ - "operator", - "owner" - ], - "properties": { - "operator": { - "type": "string" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Query metadata of token Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Returns all tokens owned by the given address, [] if unset. Return type: TokensResponse.", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Requires pagination. Lists all token_ids controlled by the contract. Return type: TokensResponse.", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw1155-base/schema/cw1155_receive_msg.json b/contracts/cw1155-base/schema/cw1155_receive_msg.json deleted file mode 100644 index 1bf693cec..000000000 --- a/contracts/cw1155-base/schema/cw1155_receive_msg.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw1155ReceiveMsg", - "description": "Cw1155ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "operator", - "token_id" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "from": { - "description": "The account that the token transfered from", - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "operator": { - "description": "The account that executed the send message", - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/instantiate_msg.json b/contracts/cw1155-base/schema/instantiate_msg.json deleted file mode 100644 index 3f5eaf0ce..000000000 --- a/contracts/cw1155-base/schema/instantiate_msg.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "description": "The minter is the only one who can create new tokens. This is designed for a base token platform that is controlled by an external program or contract.", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/is_approved_for_all_response.json b/contracts/cw1155-base/schema/is_approved_for_all_response.json deleted file mode 100644 index e3af7a983..000000000 --- a/contracts/cw1155-base/schema/is_approved_for_all_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsApprovedForAllResponse", - "type": "object", - "required": [ - "approved" - ], - "properties": { - "approved": { - "type": "boolean" - } - } -} diff --git a/contracts/cw1155-base/schema/token_info_response.json b/contracts/cw1155-base/schema/token_info_response.json deleted file mode 100644 index a94af98e3..000000000 --- a/contracts/cw1155-base/schema/token_info_response.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "description": "Should be a url point to a json file", - "type": "string" - } - } -} diff --git a/contracts/cw1155-base/schema/tokens_response.json b/contracts/cw1155-base/schema/tokens_response.json deleted file mode 100644 index b8e3d75b5..000000000 --- a/contracts/cw1155-base/schema/tokens_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_from` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/contracts/cw20-atomic-swap/schema/details_response.json b/contracts/cw20-atomic-swap/schema/details_response.json deleted file mode 100644 index efead08b7..000000000 --- a/contracts/cw20-atomic-swap/schema/details_response.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DetailsResponse", - "type": "object", - "required": [ - "balance", - "expires", - "hash", - "id", - "recipient", - "source" - ], - "properties": { - "balance": { - "description": "Balance in native tokens or cw20 token, with human-readable address", - "allOf": [ - { - "$ref": "#/definitions/BalanceHuman" - } - ] - }, - "expires": { - "description": "Once a swap is expired, it can be returned to the original source (via \"refund\").", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "hash": { - "description": "This is hex-encoded sha-256 hash of the preimage (must be 32*2 = 64 chars)", - "type": "string" - }, - "id": { - "description": "Id of this swap", - "type": "string" - }, - "recipient": { - "description": "If released, funds go to the recipient", - "type": "string" - }, - "source": { - "description": "If refunded, funds go to the source", - "type": "string" - } - }, - "definitions": { - "BalanceHuman": { - "oneOf": [ - { - "type": "object", - "required": [ - "Native" - ], - "properties": { - "Native": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "Cw20" - ], - "properties": { - "Cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-atomic-swap/schema/execute_msg.json b/contracts/cw20-atomic-swap/schema/execute_msg.json deleted file mode 100644 index 87d528567..000000000 --- a/contracts/cw20-atomic-swap/schema/execute_msg.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "create" - ], - "properties": { - "create": { - "$ref": "#/definitions/CreateMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Release sends all tokens to the recipient.", - "type": "object", - "required": [ - "release" - ], - "properties": { - "release": { - "type": "object", - "required": [ - "id", - "preimage" - ], - "properties": { - "id": { - "type": "string" - }, - "preimage": { - "description": "This is the preimage, must be exactly 32 bytes in hex (64 chars) to release: sha256(from_hex(preimage)) == from_hex(hash)", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Refund returns all remaining tokens to the original sender,", - "type": "object", - "required": [ - "refund" - ], - "properties": { - "refund": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This accepts a properly-encoded ReceiveMsg from a cw20 contract", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "CreateMsg": { - "type": "object", - "required": [ - "expires", - "hash", - "id", - "recipient" - ], - "properties": { - "expires": { - "description": "You can set expiration at time or at block height the contract is valid at. After the contract is expired, it can be returned to the original funder.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "hash": { - "description": "This is hex-encoded sha-256 hash of the preimage (must be 32*2 = 64 chars)", - "type": "string" - }, - "id": { - "description": "id is a human-readable name for the swap to use later. 3-20 bytes of utf-8 text", - "type": "string" - }, - "recipient": { - "description": "If approved, funds go to the recipient", - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-atomic-swap/schema/instantiate_msg.json b/contracts/cw20-atomic-swap/schema/instantiate_msg.json deleted file mode 100644 index 44588cf22..000000000 --- a/contracts/cw20-atomic-swap/schema/instantiate_msg.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object" -} diff --git a/contracts/cw20-atomic-swap/schema/list_response.json b/contracts/cw20-atomic-swap/schema/list_response.json deleted file mode 100644 index 47fba1bf8..000000000 --- a/contracts/cw20-atomic-swap/schema/list_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ListResponse", - "type": "object", - "required": [ - "swaps" - ], - "properties": { - "swaps": { - "description": "List all open swap ids", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/contracts/cw20-atomic-swap/schema/query_msg.json b/contracts/cw20-atomic-swap/schema/query_msg.json deleted file mode 100644 index 5d9108d31..000000000 --- a/contracts/cw20-atomic-swap/schema/query_msg.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Show all open swaps. Return type is ListResponse.", - "type": "object", - "required": [ - "list" - ], - "properties": { - "list": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns the details of the named swap, error if not created. Return type: DetailsResponse.", - "type": "object", - "required": [ - "details" - ], - "properties": { - "details": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-base/schema/all_accounts_response.json b/contracts/cw20-base/schema/all_accounts_response.json deleted file mode 100644 index cea50fba4..000000000 --- a/contracts/cw20-base/schema/all_accounts_response.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAccountsResponse", - "type": "object", - "required": [ - "accounts" - ], - "properties": { - "accounts": { - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/contracts/cw20-base/schema/all_allowances_response.json b/contracts/cw20-base/schema/all_allowances_response.json deleted file mode 100644 index 6bb2291ce..000000000 --- a/contracts/cw20-base/schema/all_allowances_response.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "allowance", - "expires", - "spender" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-base/schema/allowance_response.json b/contracts/cw20-base/schema/allowance_response.json deleted file mode 100644 index c4f98d6fc..000000000 --- a/contracts/cw20-base/schema/allowance_response.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-base/schema/balance_response.json b/contracts/cw20-base/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/contracts/cw20-base/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-base/schema/cw20_execute_msg.json b/contracts/cw20-base/schema/cw20_execute_msg.json deleted file mode 100644 index e4bc559cd..000000000 --- a/contracts/cw20-base/schema/cw20_execute_msg.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw20ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"mintable\" extension. If authorized, creates amount new tokens and adds to the recipient balance.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"marketing\" extension. If authorized, updates marketing metadata. Setting None/null for any of these will leave it unchanged. Setting Some(\"\") will clear this field on the contract storage", - "type": "object", - "required": [ - "update_marketing" - ], - "properties": { - "update_marketing": { - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "type": [ - "string", - "null" - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "If set as the \"marketing\" role on the contract, upload a new URL, SVG, or PNG for the token", - "type": "object", - "required": [ - "upload_logo" - ], - "properties": { - "upload_logo": { - "$ref": "#/definitions/Logo" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-base/schema/instantiate_msg.json b/contracts/cw20-base/schema/instantiate_msg.json deleted file mode 100644 index 7b9aa1eeb..000000000 --- a/contracts/cw20-base/schema/instantiate_msg.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "initial_balances", - "name", - "symbol" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "initial_balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "marketing": { - "anyOf": [ - { - "$ref": "#/definitions/InstantiateMarketingInfo" - }, - { - "type": "null" - } - ] - }, - "mint": { - "anyOf": [ - { - "$ref": "#/definitions/MinterResponse" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "InstantiateMarketingInfo": { - "type": "object", - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "logo": { - "anyOf": [ - { - "$ref": "#/definitions/Logo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "type": [ - "string", - "null" - ] - }, - "project": { - "type": [ - "string", - "null" - ] - } - } - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "MinterResponse": { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-base/schema/query_msg.json b/contracts/cw20-base/schema/query_msg.json deleted file mode 100644 index 369e21f07..000000000 --- a/contracts/cw20-base/schema/query_msg.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns metadata on the contract - name, decimals, supply, etc. Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"mintable\" extension. Returns who can mint and the hard cap on maximum tokens after minting. Return type: MinterResponse.", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset. Return type: AllowanceResponse.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension (and \"allowances\") Returns all allowances this owner has approved. Supports pagination. Return type: AllAllowancesResponse.", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension Returns all accounts that have balances. Supports pagination. Return type: AllAccountsResponse.", - "type": "object", - "required": [ - "all_accounts" - ], - "properties": { - "all_accounts": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Returns more metadata on the contract to display in the client: - description, logo, project url, etc. Return type: MarketingInfoResponse", - "type": "object", - "required": [ - "marketing_info" - ], - "properties": { - "marketing_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Downloads the mbeded logo data (if stored on chain). Errors if no logo data ftored for this contract. Return type: DownloadLogoResponse.", - "type": "object", - "required": [ - "download_logo" - ], - "properties": { - "download_logo": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-base/schema/token_info_response.json b/contracts/cw20-base/schema/token_info_response.json deleted file mode 100644 index 9920c841f..000000000 --- a/contracts/cw20-base/schema/token_info_response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/allowance_response.json b/contracts/cw20-bonding/schema/allowance_response.json deleted file mode 100644 index c4f98d6fc..000000000 --- a/contracts/cw20-bonding/schema/allowance_response.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/balance_response.json b/contracts/cw20-bonding/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/contracts/cw20-bonding/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/curve_info_response.json b/contracts/cw20-bonding/schema/curve_info_response.json deleted file mode 100644 index 85c4112b6..000000000 --- a/contracts/cw20-bonding/schema/curve_info_response.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CurveInfoResponse", - "type": "object", - "required": [ - "reserve", - "reserve_denom", - "spot_price", - "supply" - ], - "properties": { - "reserve": { - "$ref": "#/definitions/Uint128" - }, - "reserve_denom": { - "type": "string" - }, - "spot_price": { - "$ref": "#/definitions/Decimal" - }, - "supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/execute_msg.json b/contracts/cw20-bonding/schema/execute_msg.json deleted file mode 100644 index 647bcf381..000000000 --- a/contracts/cw20-bonding/schema/execute_msg.json +++ /dev/null @@ -1,319 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Buy will attempt to purchase as many supply tokens as possible. You must send only reserve tokens in that message", - "type": "object", - "required": [ - "buy" - ], - "properties": { - "buy": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/instantiate_msg.json b/contracts/cw20-bonding/schema/instantiate_msg.json deleted file mode 100644 index 3e968e673..000000000 --- a/contracts/cw20-bonding/schema/instantiate_msg.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "curve_type", - "decimals", - "name", - "reserve_decimals", - "reserve_denom", - "symbol" - ], - "properties": { - "curve_type": { - "description": "enum to store the curve parameters used for this contract if you want to add a custom Curve, you should make a new contract that imports this one. write a custom `instantiate`, and then dispatch `your::execute` -> `cw20_bonding::do_execute` with your custom curve as a parameter (and same with `query` -> `do_query`)", - "allOf": [ - { - "$ref": "#/definitions/CurveType" - } - ] - }, - "decimals": { - "description": "number of decimal places of the supply token, needed for proper curve math. If it is eg. BTC, where a balance of 10^8 means 1 BTC, then use 8 here.", - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "description": "name of the supply token", - "type": "string" - }, - "reserve_decimals": { - "description": "number of decimal places for the reserve token, needed for proper curve math. Same format as decimals above, eg. if it is uatom, where 1 unit is 10^-6 ATOM, use 6 here", - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "reserve_denom": { - "description": "this is the reserve token denom (only support native for now)", - "type": "string" - }, - "symbol": { - "description": "symbol / ticker of the supply token", - "type": "string" - } - }, - "definitions": { - "CurveType": { - "oneOf": [ - { - "description": "Constant always returns `value * 10^-scale` as spot price", - "type": "object", - "required": [ - "constant" - ], - "properties": { - "constant": { - "type": "object", - "required": [ - "scale", - "value" - ], - "properties": { - "scale": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Linear returns `slope * 10^-scale * supply` as spot price", - "type": "object", - "required": [ - "linear" - ], - "properties": { - "linear": { - "type": "object", - "required": [ - "scale", - "slope" - ], - "properties": { - "scale": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "slope": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", - "type": "object", - "required": [ - "square_root" - ], - "properties": { - "square_root": { - "type": "object", - "required": [ - "scale", - "slope" - ], - "properties": { - "scale": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "slope": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-bonding/schema/query_msg.json b/contracts/cw20-bonding/schema/query_msg.json deleted file mode 100644 index e28d26b41..000000000 --- a/contracts/cw20-bonding/schema/query_msg.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the reserve and supply quantities, as well as the spot price to buy 1 token", - "type": "object", - "required": [ - "curve_info" - ], - "properties": { - "curve_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns the current balance of the given address, 0 if unset.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-bonding/schema/token_info_response.json b/contracts/cw20-bonding/schema/token_info_response.json deleted file mode 100644 index 9920c841f..000000000 --- a/contracts/cw20-bonding/schema/token_info_response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-escrow/schema/details_response.json b/contracts/cw20-escrow/schema/details_response.json deleted file mode 100644 index 49aa39622..000000000 --- a/contracts/cw20-escrow/schema/details_response.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DetailsResponse", - "type": "object", - "required": [ - "arbiter", - "cw20_balance", - "cw20_whitelist", - "id", - "native_balance", - "recipient", - "source" - ], - "properties": { - "arbiter": { - "description": "arbiter can decide to approve or refund the escrow", - "type": "string" - }, - "cw20_balance": { - "description": "Balance in cw20 tokens", - "type": "array", - "items": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "cw20_whitelist": { - "description": "Whitelisted cw20 tokens", - "type": "array", - "items": { - "type": "string" - } - }, - "end_height": { - "description": "When end height set and block height exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "end_time": { - "description": "When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and block time exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "id": { - "description": "id of this escrow", - "type": "string" - }, - "native_balance": { - "description": "Balance in native tokens", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "recipient": { - "description": "if approved, funds go to the recipient", - "type": "string" - }, - "source": { - "description": "if refunded, funds go to the source", - "type": "string" - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-escrow/schema/execute_msg.json b/contracts/cw20-escrow/schema/execute_msg.json deleted file mode 100644 index 8c397b1bd..000000000 --- a/contracts/cw20-escrow/schema/execute_msg.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "create" - ], - "properties": { - "create": { - "$ref": "#/definitions/CreateMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Adds all sent native tokens to the contract", - "type": "object", - "required": [ - "top_up" - ], - "properties": { - "top_up": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Approve sends all tokens to the recipient. Only the arbiter can do this", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "description": "id is a human-readable name for the escrow from create", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Refund returns all remaining tokens to the original sender, The arbiter can do this any time, or anyone can do this after a timeout", - "type": "object", - "required": [ - "refund" - ], - "properties": { - "refund": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "description": "id is a human-readable name for the escrow from create", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This accepts a properly-encoded ReceiveMsg from a cw20 contract", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "CreateMsg": { - "type": "object", - "required": [ - "arbiter", - "id", - "recipient" - ], - "properties": { - "arbiter": { - "description": "arbiter can decide to approve or refund the escrow", - "type": "string" - }, - "cw20_whitelist": { - "description": "Besides any possible tokens sent with the CreateMsg, this is a list of all cw20 token addresses that are accepted by the escrow during a top-up. This is required to avoid a DoS attack by topping-up with an invalid cw20 contract. See https://github.com/CosmWasm/cosmwasm-plus/issues/19", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "end_height": { - "description": "When end height set and block height exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "end_time": { - "description": "When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and block time exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "id": { - "description": "id is a human-readable name for the escrow to use later 3-20 bytes of utf-8 text", - "type": "string" - }, - "recipient": { - "description": "if approved, funds go to the recipient", - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-escrow/schema/instantiate_msg.json b/contracts/cw20-escrow/schema/instantiate_msg.json deleted file mode 100644 index 44588cf22..000000000 --- a/contracts/cw20-escrow/schema/instantiate_msg.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object" -} diff --git a/contracts/cw20-escrow/schema/list_response.json b/contracts/cw20-escrow/schema/list_response.json deleted file mode 100644 index c775191a2..000000000 --- a/contracts/cw20-escrow/schema/list_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ListResponse", - "type": "object", - "required": [ - "escrows" - ], - "properties": { - "escrows": { - "description": "list all registered ids", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/contracts/cw20-escrow/schema/query_msg.json b/contracts/cw20-escrow/schema/query_msg.json deleted file mode 100644 index 8befec1aa..000000000 --- a/contracts/cw20-escrow/schema/query_msg.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Show all open escrows. Return type is ListResponse.", - "type": "object", - "required": [ - "list" - ], - "properties": { - "list": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns the details of the named escrow, error if not created Return type: DetailsResponse.", - "type": "object", - "required": [ - "details" - ], - "properties": { - "details": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-escrow/schema/receive_msg.json b/contracts/cw20-escrow/schema/receive_msg.json deleted file mode 100644 index 15dd2342b..000000000 --- a/contracts/cw20-escrow/schema/receive_msg.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ReceiveMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "create" - ], - "properties": { - "create": { - "$ref": "#/definitions/CreateMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Adds all sent native tokens to the contract", - "type": "object", - "required": [ - "top_up" - ], - "properties": { - "top_up": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "CreateMsg": { - "type": "object", - "required": [ - "arbiter", - "id", - "recipient" - ], - "properties": { - "arbiter": { - "description": "arbiter can decide to approve or refund the escrow", - "type": "string" - }, - "cw20_whitelist": { - "description": "Besides any possible tokens sent with the CreateMsg, this is a list of all cw20 token addresses that are accepted by the escrow during a top-up. This is required to avoid a DoS attack by topping-up with an invalid cw20 contract. See https://github.com/CosmWasm/cosmwasm-plus/issues/19", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "end_height": { - "description": "When end height set and block height exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "end_time": { - "description": "When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and block time exceeds this value, the escrow is expired. Once an escrow is expired, it can be returned to the original funder (via \"refund\").", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "id": { - "description": "id is a human-readable name for the escrow to use later 3-20 bytes of utf-8 text", - "type": "string" - }, - "recipient": { - "description": "if approved, funds go to the recipient", - "type": "string" - } - } - } - } -} diff --git a/contracts/cw20-ics20/schema/channel_response.json b/contracts/cw20-ics20/schema/channel_response.json deleted file mode 100644 index 89f70534d..000000000 --- a/contracts/cw20-ics20/schema/channel_response.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ChannelResponse", - "type": "object", - "required": [ - "balances", - "info", - "total_sent" - ], - "properties": { - "balances": { - "description": "How many tokens we currently have pending over this channel", - "type": "array", - "items": { - "$ref": "#/definitions/Amount" - } - }, - "info": { - "description": "Information on the channel's connection", - "allOf": [ - { - "$ref": "#/definitions/ChannelInfo" - } - ] - }, - "total_sent": { - "description": "The total number of tokens that have been sent over this channel (even if many have been returned, so balance is low)", - "type": "array", - "items": { - "$ref": "#/definitions/Amount" - } - } - }, - "definitions": { - "Amount": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-ics20/schema/execute_msg.json b/contracts/cw20-ics20/schema/execute_msg.json deleted file mode 100644 index 5c6014ed8..000000000 --- a/contracts/cw20-ics20/schema/execute_msg.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "This accepts a properly-encoded ReceiveMsg from a cw20 contract", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "This allows us to transfer *exactly one* native token", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "$ref": "#/definitions/TransferMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - } - }, - "TransferMsg": { - "description": "This is the message we accept via Receive", - "type": "object", - "required": [ - "channel", - "remote_address" - ], - "properties": { - "channel": { - "description": "The local channel to send the packets on", - "type": "string" - }, - "remote_address": { - "description": "The remote address to send to. Don't use HumanAddress as this will likely have a different Bech32 prefix than we use and cannot be validated locally", - "type": "string" - }, - "timeout": { - "description": "How long the packet lives in seconds. If not specified, use default_timeout", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-ics20/schema/init_msg.json b/contracts/cw20-ics20/schema/init_msg.json deleted file mode 100644 index 5d6d75f64..000000000 --- a/contracts/cw20-ics20/schema/init_msg.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InitMsg", - "type": "object", - "required": [ - "default_timeout" - ], - "properties": { - "default_timeout": { - "description": "Default timeout for ics20 packets, specified in seconds", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw20-ics20/schema/list_channels_response.json b/contracts/cw20-ics20/schema/list_channels_response.json deleted file mode 100644 index 69f020c93..000000000 --- a/contracts/cw20-ics20/schema/list_channels_response.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ListChannelsResponse", - "type": "object", - "required": [ - "channels" - ], - "properties": { - "channels": { - "type": "array", - "items": { - "$ref": "#/definitions/ChannelInfo" - } - } - }, - "definitions": { - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - } - } -} diff --git a/contracts/cw20-ics20/schema/port_response.json b/contracts/cw20-ics20/schema/port_response.json deleted file mode 100644 index 4561b3a72..000000000 --- a/contracts/cw20-ics20/schema/port_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PortResponse", - "type": "object", - "required": [ - "port_id" - ], - "properties": { - "port_id": { - "type": "string" - } - } -} diff --git a/contracts/cw20-ics20/schema/query_msg.json b/contracts/cw20-ics20/schema/query_msg.json deleted file mode 100644 index 10ae51822..000000000 --- a/contracts/cw20-ics20/schema/query_msg.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return the port ID bound by this contract. Returns PortResponse", - "type": "object", - "required": [ - "port" - ], - "properties": { - "port": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Show all channels we have connected to. Return type is ListChannelsResponse.", - "type": "object", - "required": [ - "list_channels" - ], - "properties": { - "list_channels": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns the details of the name channel, error if not created. Return type: ChannelResponse.", - "type": "object", - "required": [ - "channel" - ], - "properties": { - "channel": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-ics20/schema/transfer_msg.json b/contracts/cw20-ics20/schema/transfer_msg.json deleted file mode 100644 index ca47b20f8..000000000 --- a/contracts/cw20-ics20/schema/transfer_msg.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TransferMsg", - "description": "This is the message we accept via Receive", - "type": "object", - "required": [ - "channel", - "remote_address" - ], - "properties": { - "channel": { - "description": "The local channel to send the packets on", - "type": "string" - }, - "remote_address": { - "description": "The remote address to send to. Don't use HumanAddress as this will likely have a different Bech32 prefix than we use and cannot be validated locally", - "type": "string" - }, - "timeout": { - "description": "How long the packet lives in seconds. If not specified, use default_timeout", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/config_response.json b/contracts/cw20-merkle-airdrop/schema/config_response.json deleted file mode 100644 index a4db8a7a7..000000000 --- a/contracts/cw20-merkle-airdrop/schema/config_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "cw20_token_address" - ], - "properties": { - "cw20_token_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/execute_msg.json b/contracts/cw20-merkle-airdrop/schema/execute_msg.json deleted file mode 100644 index b4051d719..000000000 --- a/contracts/cw20-merkle-airdrop/schema/execute_msg.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "update_config" - ], - "properties": { - "update_config": { - "type": "object", - "properties": { - "new_owner": { - "description": "NewOwner if non sent, contract gets locked. Recipients can receive airdrops but owner cannot register new stages.", - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_merkle_root" - ], - "properties": { - "register_merkle_root": { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Claim does not check if contract has enough funds, owner must ensure it.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "amount", - "proof", - "stage" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "proof": { - "description": "Proof is hex-encoded merkle proof.", - "type": "array", - "items": { - "type": "string" - } - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/instantiate_msg.json b/contracts/cw20-merkle-airdrop/schema/instantiate_msg.json deleted file mode 100644 index 313cad00c..000000000 --- a/contracts/cw20-merkle-airdrop/schema/instantiate_msg.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "cw20_token_address" - ], - "properties": { - "cw20_token_address": { - "type": "string" - }, - "owner": { - "description": "Owner if none set to info.sender.", - "type": [ - "string", - "null" - ] - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/is_claimed_response.json b/contracts/cw20-merkle-airdrop/schema/is_claimed_response.json deleted file mode 100644 index bc7fe782a..000000000 --- a/contracts/cw20-merkle-airdrop/schema/is_claimed_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClaimedResponse", - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "boolean" - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/latest_stage_response.json b/contracts/cw20-merkle-airdrop/schema/latest_stage_response.json deleted file mode 100644 index 4e274dc23..000000000 --- a/contracts/cw20-merkle-airdrop/schema/latest_stage_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "LatestStageResponse", - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/merkle_root_response.json b/contracts/cw20-merkle-airdrop/schema/merkle_root_response.json deleted file mode 100644 index 101b49f11..000000000 --- a/contracts/cw20-merkle-airdrop/schema/merkle_root_response.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MerkleRootResponse", - "type": "object", - "required": [ - "merkle_root", - "stage" - ], - "properties": { - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw20-merkle-airdrop/schema/query_msg.json b/contracts/cw20-merkle-airdrop/schema/query_msg.json deleted file mode 100644 index 78da096b6..000000000 --- a/contracts/cw20-merkle-airdrop/schema/query_msg.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "merkle_root": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "object", - "required": [ - "address", - "stage" - ], - "properties": { - "address": { - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-staking/schema/allowance_response.json b/contracts/cw20-staking/schema/allowance_response.json deleted file mode 100644 index c4f98d6fc..000000000 --- a/contracts/cw20-staking/schema/allowance_response.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/balance_response.json b/contracts/cw20-staking/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/contracts/cw20-staking/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/claims_response.json b/contracts/cw20-staking/schema/claims_response.json deleted file mode 100644 index 08211a3c8..000000000 --- a/contracts/cw20-staking/schema/claims_response.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClaimsResponse", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "array", - "items": { - "$ref": "#/definitions/Claim" - } - } - }, - "definitions": { - "Claim": { - "type": "object", - "required": [ - "amount", - "release_at" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "release_at": { - "$ref": "#/definitions/Expiration" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/execute_msg.json b/contracts/cw20-staking/schema/execute_msg.json deleted file mode 100644 index 505a88d8d..000000000 --- a/contracts/cw20-staking/schema/execute_msg.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Bond will bond all staking tokens sent with the message and release derivative tokens", - "type": "object", - "required": [ - "bond" - ], - "properties": { - "bond": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", - "type": "object", - "required": [ - "unbond" - ], - "properties": { - "unbond": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Reinvest will check for all accumulated rewards, withdraw them, and re-bond them to the same validator. Anyone can call this, which updates the value of the token (how much under custody).", - "type": "object", - "required": [ - "reinvest" - ], - "properties": { - "reinvest": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "_BondAllTokens can only be called by the contract itself, after all rewards have been withdrawn. This is an example of using \"callbacks\" in message flows. This can only be invoked by the contract itself as a return from Reinvest", - "type": "object", - "required": [ - "__bond_all_tokens" - ], - "properties": { - "__bond_all_tokens": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/instantiate_msg.json b/contracts/cw20-staking/schema/instantiate_msg.json deleted file mode 100644 index 9979bf2ab..000000000 --- a/contracts/cw20-staking/schema/instantiate_msg.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "exit_tax", - "min_withdrawal", - "name", - "symbol", - "unbonding_period", - "validator" - ], - "properties": { - "decimals": { - "description": "decimal places of the derivative token (for UI)", - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "exit_tax": { - "description": "this is how much the owner takes as a cut when someone unbonds", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] - }, - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "name": { - "description": "name of the derivative token", - "type": "string" - }, - "symbol": { - "description": "symbol / ticker of the derivative token", - "type": "string" - }, - "unbonding_period": { - "description": "This is the unbonding period of the native staking module We need this to only allow claims to be redeemed after the money has arrived", - "allOf": [ - { - "$ref": "#/definitions/Duration" - } - ] - }, - "validator": { - "description": "This is the validator that all tokens will be bonded to", - "type": "string" - } - }, - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/investment_response.json b/contracts/cw20-staking/schema/investment_response.json deleted file mode 100644 index c79ca56d3..000000000 --- a/contracts/cw20-staking/schema/investment_response.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InvestmentResponse", - "type": "object", - "required": [ - "exit_tax", - "min_withdrawal", - "nominal_value", - "owner", - "staked_tokens", - "token_supply", - "validator" - ], - "properties": { - "exit_tax": { - "description": "this is how much the owner takes as a cut when someone unbonds", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] - }, - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "nominal_value": { - "$ref": "#/definitions/Decimal" - }, - "owner": { - "description": "owner created the contract and takes a cut", - "type": "string" - }, - "staked_tokens": { - "$ref": "#/definitions/Coin" - }, - "token_supply": { - "$ref": "#/definitions/Uint128" - }, - "validator": { - "description": "All tokens are bonded to this validator", - "type": "string" - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw20-staking/schema/query_msg.json b/contracts/cw20-staking/schema/query_msg.json deleted file mode 100644 index bca894a7f..000000000 --- a/contracts/cw20-staking/schema/query_msg.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Claims shows the number of tokens this address can access when they are done unbonding", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Investment shows metadata on the staking info of the contract", - "type": "object", - "required": [ - "investment" - ], - "properties": { - "investment": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns the current balance of the given address, 0 if unset.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw20-staking/schema/token_info_response.json b/contracts/cw20-staking/schema/token_info_response.json deleted file mode 100644 index 9920c841f..000000000 --- a/contracts/cw20-staking/schema/token_info_response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw3-fixed-multisig/schema/execute_msg.json b/contracts/cw3-fixed-multisig/schema/execute_msg.json deleted file mode 100644 index 3c29a4fb6..000000000 --- a/contracts/cw3-fixed-multisig/schema/execute_msg.json +++ /dev/null @@ -1,642 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "propose" - ], - "properties": { - "propose": { - "type": "object", - "required": [ - "description", - "msgs", - "title" - ], - "properties": { - "description": { - "type": "string" - }, - "latest": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - }, - "title": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/Vote" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "close" - ], - "properties": { - "close": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Vote": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "veto" - ] - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw3-fixed-multisig/schema/instantiate_msg.json b/contracts/cw3-fixed-multisig/schema/instantiate_msg.json deleted file mode 100644 index cabbc8d0b..000000000 --- a/contracts/cw3-fixed-multisig/schema/instantiate_msg.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "max_voting_period", - "required_weight", - "voters" - ], - "properties": { - "max_voting_period": { - "$ref": "#/definitions/Duration" - }, - "required_weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "voters": { - "type": "array", - "items": { - "$ref": "#/definitions/Voter" - } - } - }, - "definitions": { - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Voter": { - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/contracts/cw3-fixed-multisig/schema/query_msg.json b/contracts/cw3-fixed-multisig/schema/query_msg.json deleted file mode 100644 index 42aea7141..000000000 --- a/contracts/cw3-fixed-multisig/schema/query_msg.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return ThresholdResponse", - "type": "object", - "required": [ - "threshold" - ], - "properties": { - "threshold": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalResponse", - "type": "object", - "required": [ - "proposal" - ], - "properties": { - "proposal": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalListResponse", - "type": "object", - "required": [ - "list_proposals" - ], - "properties": { - "list_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalListResponse", - "type": "object", - "required": [ - "reverse_proposals" - ], - "properties": { - "reverse_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_before": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoteResponse", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "voter" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "voter": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoteListResponse", - "type": "object", - "required": [ - "list_votes" - ], - "properties": { - "list_votes": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoterInfo", - "type": "object", - "required": [ - "voter" - ], - "properties": { - "voter": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoterListResponse", - "type": "object", - "required": [ - "list_voters" - ], - "properties": { - "list_voters": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw3-flex-multisig/schema/execute_msg.json b/contracts/cw3-flex-multisig/schema/execute_msg.json deleted file mode 100644 index 62a31181e..000000000 --- a/contracts/cw3-flex-multisig/schema/execute_msg.json +++ /dev/null @@ -1,698 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "propose" - ], - "properties": { - "propose": { - "type": "object", - "required": [ - "description", - "msgs", - "title" - ], - "properties": { - "description": { - "type": "string" - }, - "latest": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "msgs": { - "type": "array", - "items": { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - }, - "title": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/Vote" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "close" - ], - "properties": { - "close": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Handles update hook messages from the group contract", - "type": "object", - "required": [ - "member_changed_hook" - ], - "properties": { - "member_changed_hook": { - "$ref": "#/definitions/MemberChangedHookMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "MemberChangedHookMsg": { - "description": "MemberChangedHookMsg should be de/serialized under `MemberChangedHook()` variant in a ExecuteMsg. This contains a list of all diffs on the given transaction.", - "type": "object", - "required": [ - "diffs" - ], - "properties": { - "diffs": { - "type": "array", - "items": { - "$ref": "#/definitions/MemberDiff" - } - } - } - }, - "MemberDiff": { - "description": "MemberDiff shows the old and new states for a given cw4 member They cannot both be None. old = None, new = Some -> Insert old = Some, new = Some -> Update old = Some, new = None -> Delete", - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - }, - "new": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "old": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Vote": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "veto" - ] - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw3-flex-multisig/schema/instantiate_msg.json b/contracts/cw3-flex-multisig/schema/instantiate_msg.json deleted file mode 100644 index 42c078f66..000000000 --- a/contracts/cw3-flex-multisig/schema/instantiate_msg.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "group_addr", - "max_voting_period", - "threshold" - ], - "properties": { - "group_addr": { - "type": "string" - }, - "max_voting_period": { - "$ref": "#/definitions/Duration" - }, - "threshold": { - "$ref": "#/definitions/Threshold" - } - }, - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Threshold": { - "description": "This defines the different ways tallies can happen.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation). See also `ThresholdResponse` in the cw3 spec.", - "oneOf": [ - { - "description": "Declares that a fixed weight of Yes votes is needed to pass. See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details.", - "type": "object", - "required": [ - "absolute_count" - ], - "properties": { - "absolute_count": { - "type": "object", - "required": [ - "weight" - ], - "properties": { - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Declares a percentage of the total weight that must cast Yes votes in order for a proposal to pass. See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details.", - "type": "object", - "required": [ - "absolute_percentage" - ], - "properties": { - "absolute_percentage": { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details.", - "type": "object", - "required": [ - "threshold_quorum" - ], - "properties": { - "threshold_quorum": { - "type": "object", - "required": [ - "quorum", - "threshold" - ], - "properties": { - "quorum": { - "$ref": "#/definitions/Decimal" - }, - "threshold": { - "$ref": "#/definitions/Decimal" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/contracts/cw3-flex-multisig/schema/query_msg.json b/contracts/cw3-flex-multisig/schema/query_msg.json deleted file mode 100644 index 42aea7141..000000000 --- a/contracts/cw3-flex-multisig/schema/query_msg.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return ThresholdResponse", - "type": "object", - "required": [ - "threshold" - ], - "properties": { - "threshold": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalResponse", - "type": "object", - "required": [ - "proposal" - ], - "properties": { - "proposal": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalListResponse", - "type": "object", - "required": [ - "list_proposals" - ], - "properties": { - "list_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns ProposalListResponse", - "type": "object", - "required": [ - "reverse_proposals" - ], - "properties": { - "reverse_proposals": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_before": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoteResponse", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "voter" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "voter": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoteListResponse", - "type": "object", - "required": [ - "list_votes" - ], - "properties": { - "list_votes": { - "type": "object", - "required": [ - "proposal_id" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoterInfo", - "type": "object", - "required": [ - "voter" - ], - "properties": { - "voter": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns VoterListResponse", - "type": "object", - "required": [ - "list_voters" - ], - "properties": { - "list_voters": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw4-group/schema/admin_response.json b/contracts/cw4-group/schema/admin_response.json deleted file mode 100644 index 82bf62a3a..000000000 --- a/contracts/cw4-group/schema/admin_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminResponse", - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } -} diff --git a/contracts/cw4-group/schema/execute_msg.json b/contracts/cw4-group/schema/execute_msg.json deleted file mode 100644 index 4322f89a9..000000000 --- a/contracts/cw4-group/schema/execute_msg.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Change the admin", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "apply a diff to the existing members. remove is applied after add, so if an address is in both, it is removed", - "type": "object", - "required": [ - "update_members" - ], - "properties": { - "update_members": { - "type": "object", - "required": [ - "add", - "remove" - ], - "properties": { - "add": { - "type": "array", - "items": { - "$ref": "#/definitions/Member" - } - }, - "remove": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Add a new hook to be informed of all membership changes. Must be called by Admin", - "type": "object", - "required": [ - "add_hook" - ], - "properties": { - "add_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove a hook. Must be called by Admin", - "type": "object", - "required": [ - "remove_hook" - ], - "properties": { - "remove_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Member": { - "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/contracts/cw4-group/schema/instantiate_msg.json b/contracts/cw4-group/schema/instantiate_msg.json deleted file mode 100644 index efa676c03..000000000 --- a/contracts/cw4-group/schema/instantiate_msg.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "members" - ], - "properties": { - "admin": { - "description": "The admin is the only account that can update the group state. Omit it to make the group immutable.", - "type": [ - "string", - "null" - ] - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/Member" - } - } - }, - "definitions": { - "Member": { - "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/contracts/cw4-group/schema/member_list_response.json b/contracts/cw4-group/schema/member_list_response.json deleted file mode 100644 index ae09f9bba..000000000 --- a/contracts/cw4-group/schema/member_list_response.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberListResponse", - "type": "object", - "required": [ - "members" - ], - "properties": { - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/Member" - } - } - }, - "definitions": { - "Member": { - "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/contracts/cw4-group/schema/member_response.json b/contracts/cw4-group/schema/member_response.json deleted file mode 100644 index c78ed8623..000000000 --- a/contracts/cw4-group/schema/member_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberResponse", - "type": "object", - "properties": { - "weight": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw4-group/schema/query_msg.json b/contracts/cw4-group/schema/query_msg.json deleted file mode 100644 index f7987c626..000000000 --- a/contracts/cw4-group/schema/query_msg.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return AdminResponse", - "type": "object", - "required": [ - "admin" - ], - "properties": { - "admin": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Return TotalWeightResponse", - "type": "object", - "required": [ - "total_weight" - ], - "properties": { - "total_weight": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns MembersListResponse", - "type": "object", - "required": [ - "list_members" - ], - "properties": { - "list_members": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns MemberResponse", - "type": "object", - "required": [ - "member" - ], - "properties": { - "member": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - }, - "at_height": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Shows all registered hooks. Returns HooksResponse.", - "type": "object", - "required": [ - "hooks" - ], - "properties": { - "hooks": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw4-group/schema/total_weight_response.json b/contracts/cw4-group/schema/total_weight_response.json deleted file mode 100644 index 61db7a998..000000000 --- a/contracts/cw4-group/schema/total_weight_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalWeightResponse", - "type": "object", - "required": [ - "weight" - ], - "properties": { - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw4-stake/schema/admin_response.json b/contracts/cw4-stake/schema/admin_response.json deleted file mode 100644 index 82bf62a3a..000000000 --- a/contracts/cw4-stake/schema/admin_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AdminResponse", - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } -} diff --git a/contracts/cw4-stake/schema/claims_response.json b/contracts/cw4-stake/schema/claims_response.json deleted file mode 100644 index 08211a3c8..000000000 --- a/contracts/cw4-stake/schema/claims_response.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClaimsResponse", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "array", - "items": { - "$ref": "#/definitions/Claim" - } - } - }, - "definitions": { - "Claim": { - "type": "object", - "required": [ - "amount", - "release_at" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "release_at": { - "$ref": "#/definitions/Expiration" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw4-stake/schema/execute_msg.json b/contracts/cw4-stake/schema/execute_msg.json deleted file mode 100644 index 4b627d09d..000000000 --- a/contracts/cw4-stake/schema/execute_msg.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Bond will bond all staking tokens sent with the message and update membership weight", - "type": "object", - "required": [ - "bond" - ], - "properties": { - "bond": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Unbond will start the unbonding process for the given number of tokens. The sender immediately loses weight from these tokens, and can claim them back to his wallet after `unbonding_period`", - "type": "object", - "required": [ - "unbond" - ], - "properties": { - "unbond": { - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the contract-defined waiting period (eg. 1 week)", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Change the admin", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Add a new hook to be informed of all membership changes. Must be called by Admin", - "type": "object", - "required": [ - "add_hook" - ], - "properties": { - "add_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove a hook. Must be called by Admin", - "type": "object", - "required": [ - "remove_hook" - ], - "properties": { - "remove_hook": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This accepts a properly-encoded ReceiveMsg from a cw20 contract", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw4-stake/schema/instantiate_msg.json b/contracts/cw4-stake/schema/instantiate_msg.json deleted file mode 100644 index d996eda1c..000000000 --- a/contracts/cw4-stake/schema/instantiate_msg.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "denom", - "min_bond", - "tokens_per_weight", - "unbonding_period" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "denom": { - "description": "denom of the token to stake", - "allOf": [ - { - "$ref": "#/definitions/Denom" - } - ] - }, - "min_bond": { - "$ref": "#/definitions/Uint128" - }, - "tokens_per_weight": { - "$ref": "#/definitions/Uint128" - }, - "unbonding_period": { - "$ref": "#/definitions/Duration" - } - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Denom": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw4-stake/schema/member_list_response.json b/contracts/cw4-stake/schema/member_list_response.json deleted file mode 100644 index ae09f9bba..000000000 --- a/contracts/cw4-stake/schema/member_list_response.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberListResponse", - "type": "object", - "required": [ - "members" - ], - "properties": { - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/Member" - } - } - }, - "definitions": { - "Member": { - "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", - "type": "object", - "required": [ - "addr", - "weight" - ], - "properties": { - "addr": { - "type": "string" - }, - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - } -} diff --git a/contracts/cw4-stake/schema/member_response.json b/contracts/cw4-stake/schema/member_response.json deleted file mode 100644 index c78ed8623..000000000 --- a/contracts/cw4-stake/schema/member_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MemberResponse", - "type": "object", - "properties": { - "weight": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/contracts/cw4-stake/schema/query_msg.json b/contracts/cw4-stake/schema/query_msg.json deleted file mode 100644 index 33d7a6c52..000000000 --- a/contracts/cw4-stake/schema/query_msg.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Claims shows the tokens in process of unbonding for this address", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staked" - ], - "properties": { - "staked": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return AdminResponse", - "type": "object", - "required": [ - "admin" - ], - "properties": { - "admin": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Return TotalWeightResponse", - "type": "object", - "required": [ - "total_weight" - ], - "properties": { - "total_weight": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns MembersListResponse", - "type": "object", - "required": [ - "list_members" - ], - "properties": { - "list_members": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns MemberResponse", - "type": "object", - "required": [ - "member" - ], - "properties": { - "member": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "string" - }, - "at_height": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Shows all registered hooks. Returns HooksResponse.", - "type": "object", - "required": [ - "hooks" - ], - "properties": { - "hooks": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw4-stake/schema/receive_msg.json b/contracts/cw4-stake/schema/receive_msg.json deleted file mode 100644 index ea681d68b..000000000 --- a/contracts/cw4-stake/schema/receive_msg.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ReceiveMsg", - "oneOf": [ - { - "description": "Only valid cw20 message is to bond the tokens", - "type": "object", - "required": [ - "bond" - ], - "properties": { - "bond": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/cw4-stake/schema/staked_response.json b/contracts/cw4-stake/schema/staked_response.json deleted file mode 100644 index ab5fcb992..000000000 --- a/contracts/cw4-stake/schema/staked_response.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StakedResponse", - "type": "object", - "required": [ - "denom", - "stake" - ], - "properties": { - "denom": { - "$ref": "#/definitions/Denom" - }, - "stake": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Denom": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/contracts/cw4-stake/schema/total_weight_response.json b/contracts/cw4-stake/schema/total_weight_response.json deleted file mode 100644 index 61db7a998..000000000 --- a/contracts/cw4-stake/schema/total_weight_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalWeightResponse", - "type": "object", - "required": [ - "weight" - ], - "properties": { - "weight": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} From 0925703ad9fc28638176c9c531618345da63973e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 16:09:49 +0100 Subject: [PATCH 073/631] Update gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 58379de3e..62abf6fb6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,7 @@ contracts.txt artifacts/ # code coverage -tarpaulin-report.* \ No newline at end of file +tarpaulin-report.* + +packages/*/schema +contracts/*/schema From 466b1c82dcd8a8b4224acd62f8c68ed549b4b5b3 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 21 Dec 2021 17:22:45 +0100 Subject: [PATCH 074/631] Add MIGRATING.md Add breaking changes list / migration points for 0.10.x to 0.11.0 --- MIGRATING.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 MIGRATING.md diff --git a/MIGRATING.md b/MIGRATING.md new file mode 100644 index 000000000..9c08f1621 --- /dev/null +++ b/MIGRATING.md @@ -0,0 +1,115 @@ +# Migrating + +This guide lists API changes between *cw-plus* major releases. + +## v0.10.3 -> v0.11.0 + +### Breaking Issues / PRs + +- Rename cw0 to utils [\#471](https://github.com/CosmWasm/cw-plus/issues/471) / Cw0 rename [\#508](https://github.com/CosmWasm/cw-plus/pull/508) + +The `cw0` package was renamed to `utils`. The required changes are straightforward: + +```diff +diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml +index 1924b655..37af477d 100644 +--- a/contracts/cw1-subkeys/Cargo.toml ++++ b/contracts/cw1-subkeys/Cargo.toml +@@ -19,7 +19,7 @@ library = [] + test-utils = [] + + [dependencies] +-cw0 = { path = "../../packages/cw0", version = "0.10.3" } ++utils = { path = "../../packages/utils", version = "0.10.3" } + cw1 = { path = "../../packages/cw1", version = "0.10.3" } + cw2 = { path = "../../packages/cw2", version = "0.10.3" } + cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library"] } +``` + +```diff +diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs +index b4852225..f20a65ec 100644 +--- a/contracts/cw1-subkeys/src/contract.rs ++++ b/contracts/cw1-subkeys/src/contract.rs +@@ -8,7 +8,6 @@ use cosmwasm_std::{ + ensure, ensure_ne, to_binary, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg, + Empty, Env, MessageInfo, Order, Response, StakingMsg, StdResult, + }; +-use cw0::Expiration; + use cw1::CanExecuteResponse; + use cw1_whitelist::{ + contract::{ +@@ -21,6 +20,7 @@ use cw1_whitelist::{ + use cw2::{get_contract_version, set_contract_version}; + use cw_storage_plus::Bound; + use semver::Version; ++use utils::Expiration; + + use crate::error::ContractError; + use crate::msg::{ +``` + +- Deprecate `range` to `range_raw` [\#460](https://github.com/CosmWasm/cw-plus/issues/460) / +`range` to `range raw` [\#576](https://github.com/CosmWasm/cw-plus/pull/576). + +`range` was renamed to `range_raw` (no key deserialization), and `range_de` to `range`. This means you can now count +on the key to be deserialized for you, which results in cleaner / simpler code. + +There are many examples in the contracts code base, by example: +```diff + +``` + +If / when you don't need key deserialization, just can just rename `range` to `range_raw` and you are good to go. + +If you need / want key deserialization for **indexes**, you need to specify the primary key type as a last (optional) +argument in the index key specification. If not specified, it defaults to `()`, which means that primary keys will +not only not be deserialized, but also not provided. This is for backwards-compatibility with current indexes +specifications, and may change in the future once these features are stabilized. + +Also, as part of this issue, `keys` was renamed to `keys_raw`, and `keys_de` to `keys`. `prefix_range` was also renamed, +to `prefix_range_raw`, and its key deserialization counterpart (`prefix_range_de`) to `prefix_range` in turn. + +Finally, this applies to all the `Map`-like types, including indexed maps. + +- `UniqueIndex` / `MultiIndex` key consistency [\#532](https://github.com/CosmWasm/cw-plus/issues/532) / +Index keys consistency [\#568](https://github.com/CosmWasm/cw-plus/pull/568) + +For both `UniqueIndex` and `MultiIndex`, returned keys (deserialized or not) are now the associated *primary keys* of +the data. This is a breaking change for `MultiIndex`, as the previous version returned a composite of the index key and +the primary key. + +Required changes are: +```diff +``` + +- Remove the primary key from the `MultiIndex` key specification [\#533](https://github.com/CosmWasm/cw-plus/issues/533) / +`MultiIndex` primary key spec removal [\#569](https://github.com/CosmWasm/cw-plus/pull/569) + +The primary key is no longer needed when specifying `MultiIndex` keys. This simplifies both `MultiIndex` definitions +and usage. + +Required changes are along the lines of: +```diff +``` + +- Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) / +Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) + +As part of range iterators revamping, we fixed the order of signed integer keys. You shouldn't change anything in your +code base for this, but if you were using signed keys and relying on their ordering, that has now changed for the better. +Take into account also that **the internal representation of signed integer keys has changed**. So, if you +have data stored under signed integer keys you would need to **migrate it**, or recreate it under the new representation. + +As part of this, a couple helpers for handling int keys serialization and deserialization were introduced: + - `from_cw_bytes` Integer (signed and unsigned) values deserialization. + - `to_cw_bytes` - Integer (signed and unsigned) values serialization. + +You shouldn't need these, except when manually handling raw integer keys serialization / deserialization. + +### Non-breaking Issues / PRs + +- Deprecate `IntKey` [\#472](https://github.com/CosmWasm/cw-plus/issues/472) / +Deprecate IntKey [\#547](https://github.com/CosmWasm/cw-plus/pull/547) + +See [CHANGELOG.md](CHANGELOG.md) for the full list. From d32cadfa7edd1b567124365d274200c06aca6ee9 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:10:14 +0100 Subject: [PATCH 075/631] Add / simplify migation code examples --- MIGRATING.md | 149 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 24 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index 9c08f1621..8b5df4b54 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -15,15 +15,8 @@ diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 1924b655..37af477d 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml -@@ -19,7 +19,7 @@ library = [] - test-utils = [] - - [dependencies] -cw0 = { path = "../../packages/cw0", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.10.3" } - cw1 = { path = "../../packages/cw1", version = "0.10.3" } - cw2 = { path = "../../packages/cw2", version = "0.10.3" } - cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library"] } ``` ```diff @@ -31,22 +24,8 @@ diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/c index b4852225..f20a65ec 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs -@@ -8,7 +8,6 @@ use cosmwasm_std::{ - ensure, ensure_ne, to_binary, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg, - Empty, Env, MessageInfo, Order, Response, StakingMsg, StdResult, - }; -use cw0::Expiration; - use cw1::CanExecuteResponse; - use cw1_whitelist::{ - contract::{ -@@ -21,6 +20,7 @@ use cw1_whitelist::{ - use cw2::{get_contract_version, set_contract_version}; - use cw_storage_plus::Bound; - use semver::Version; +use utils::Expiration; - - use crate::error::ContractError; - use crate::msg::{ ``` - Deprecate `range` to `range_raw` [\#460](https://github.com/CosmWasm/cw-plus/issues/460) / @@ -55,9 +34,40 @@ index b4852225..f20a65ec 100644 `range` was renamed to `range_raw` (no key deserialization), and `range_de` to `range`. This means you can now count on the key to be deserialized for you, which results in cleaner / simpler code. -There are many examples in the contracts code base, by example: +There are some examples in the contracts code base, by example: ```diff - +diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs +index 48a60083..2f2ef70d 100644 +--- a/contracts/cw3-fixed-multisig/src/contract.rs ++++ b/contracts/cw3-fixed-multisig/src/contract.rs +@@ -385,21 +384,20 @@ fn list_votes( + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.map(Bound::exclusive); + +- let votes: StdResult> = BALLOTS ++ let votes = BALLOTS + .prefix(proposal_id) +- .range_raw(deps.storage, start, None, Order::Ascending) ++ .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { +- let (key, ballot) = item?; +- Ok(VoteInfo { +- voter: String::from_utf8(key)?, ++ item.map(|(addr, ballot)| VoteInfo { ++ voter: addr.into(), + vote: ballot.vote, + weight: ballot.weight, + }) + }) +- .collect(); ++ .collect::>()?; + +- Ok(VoteListResponse { votes: votes? }) ++ Ok(VoteListResponse { votes }) + } + + fn query_voter(deps: Deps, voter: String) -> StdResult { ``` If / when you don't need key deserialization, just can just rename `range` to `range_raw` and you are good to go. @@ -66,6 +76,7 @@ If you need / want key deserialization for **indexes**, you need to specify the argument in the index key specification. If not specified, it defaults to `()`, which means that primary keys will not only not be deserialized, but also not provided. This is for backwards-compatibility with current indexes specifications, and may change in the future once these features are stabilized. +See `packages/storage-plus/src/indexed_map.rs` tests for reference. Also, as part of this issue, `keys` was renamed to `keys_raw`, and `keys_de` to `keys`. `prefix_range` was also renamed, to `prefix_range_raw`, and its key deserialization counterpart (`prefix_range_de`) to `prefix_range` in turn. @@ -79,8 +90,59 @@ For both `UniqueIndex` and `MultiIndex`, returned keys (deserialized or not) are the data. This is a breaking change for `MultiIndex`, as the previous version returned a composite of the index key and the primary key. -Required changes are: +Examples of required changes are: ```diff +diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs +index 9f7178af..d11d501e 100644 +--- a/packages/storage-plus/src/indexed_map.rs ++++ b/packages/storage-plus/src/indexed_map.rs +@@ -722,7 +722,7 @@ mod test { + last_name: "".to_string(), + age: 42, + }; +- let pk1: &[u8] = b"5627"; ++ let pk1: &str = "5627"; + map.save(&mut store, pk1, &data1).unwrap(); + + let data2 = Data { +@@ -730,7 +730,7 @@ mod test { + last_name: "Perez".to_string(), + age: 13, + }; +- let pk2: &[u8] = b"5628"; ++ let pk2: &str = "5628"; + map.save(&mut store, pk2, &data2).unwrap(); + + let data3 = Data { +@@ -738,7 +738,7 @@ mod test { + last_name: "Young".to_string(), + age: 24, + }; +- let pk3: &[u8] = b"5629"; ++ let pk3: &str = "5629"; + map.save(&mut store, pk3, &data3).unwrap(); + + let data4 = Data { +@@ -746,7 +746,7 @@ mod test { + last_name: "Bemberg".to_string(), + age: 43, + }; +- let pk4: &[u8] = b"5630"; ++ let pk4: &str = "5630"; + map.save(&mut store, pk4, &data4).unwrap(); + + let marias: Vec<_> = map +@@ -760,8 +760,8 @@ mod test { + assert_eq!(2, count); + + // Remaining part (age) of the index keys, plus pks (bytes) (sorted by age descending) +- assert_eq!((42, pk1.to_vec()), marias[0].0); +- assert_eq!((24, pk3.to_vec()), marias[1].0); ++ assert_eq!(pk1, marias[0].0); ++ assert_eq!(pk3, marias[1].0); + + // Data + assert_eq!(data1, marias[0].1); ``` - Remove the primary key from the `MultiIndex` key specification [\#533](https://github.com/CosmWasm/cw-plus/issues/533) / @@ -91,6 +153,45 @@ and usage. Required changes are along the lines of: ```diff +diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs +index 022a4504..c7a3bb9d 100644 +--- a/packages/storage-plus/src/indexed_map.rs ++++ b/packages/storage-plus/src/indexed_map.rs +@@ -295,8 +295,8 @@ mod test { + } + + struct DataIndexes<'a> { +- // Second arg is for storing pk +- pub name: MultiIndex<'a, (String, String), Data, String>, ++ // Last args are for signaling pk deserialization ++ pub name: MultiIndex<'a, String, Data, String>, + pub age: UniqueIndex<'a, u32, Data, String>, + pub name_lastname: UniqueIndex<'a, (Vec, Vec), Data, String>, + } +@@ -326,11 +326,7 @@ mod test { + // Can we make it easier to define this? (less wordy generic) + fn build_map<'a>() -> IndexedMap<'a, &'a str, Data, DataIndexes<'a>> { + let indexes = DataIndexes { +- name: MultiIndex::new( +- |d, k| (d.name.clone(), unsafe { String::from_utf8_unchecked(k) }), +- "data", +- "data__name", +- ), ++ name: MultiIndex::new(|d| d.name.clone(), "data", "data__name"), + age: UniqueIndex::new(|d| d.age, "data__age"), + name_lastname: UniqueIndex::new( + |d| index_string_tuple(&d.name, &d.last_name), +@@ -469,8 +462,8 @@ mod test { + // index_key() over MultiIndex works (empty pk) + // In a MultiIndex, an 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()); +- // Use the index_key() helper to build the (raw) index key ++ 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 ``` - Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) / From 3085c2ac31b97b79d48829aee242496b565d110f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:18:33 +0100 Subject: [PATCH 076/631] Add extra example for int keys migration --- MIGRATING.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/MIGRATING.md b/MIGRATING.md index 8b5df4b54..fca504b82 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -213,4 +213,30 @@ You shouldn't need these, except when manually handling raw integer keys seriali - Deprecate `IntKey` [\#472](https://github.com/CosmWasm/cw-plus/issues/472) / Deprecate IntKey [\#547](https://github.com/CosmWasm/cw-plus/pull/547) -See [CHANGELOG.md](CHANGELOG.md) for the full list. +The `IntKey` wrapper and its type aliases are marked as deprecated, and will be removed in the next major version. +The migration is straightforward, just remove the wrappers: +```diff +diff --git a/contracts/cw20-merkle-airdrop/src/contract.rs b/contracts/cw20-merkle-airdrop/src/contract.rs +index e8d5ea57..bdf555e8 100644 +--- a/contracts/cw20-merkle-airdrop/src/contract.rs ++++ b/contracts/cw20-merkle-airdrop/src/contract.rs +@@ -6,7 +6,6 @@ use cosmwasm_std::{ + }; + use cw2::{get_contract_version, set_contract_version}; + use cw20::Cw20ExecuteMsg; +-use cw_storage_plus::U8Key; + use sha2::Digest; + use std::convert::TryInto; + +@@ -113,7 +112,7 @@ pub fn execute_register_merkle_root( + + let stage = LATEST_STAGE.update(deps.storage, |stage| -> StdResult<_> { Ok(stage + 1) })?; + +- MERKLE_ROOT.save(deps.storage, U8Key::from(stage), &merkle_root)?; ++ MERKLE_ROOT.save(deps.storage, stage, &merkle_root)?; + LATEST_STAGE.save(deps.storage, &stage)?; + + Ok(Response::new().add_attributes(vec![ +``` + +- See [CHANGELOG.md](CHANGELOG.md) for the full list of non-breaking changes. From c14ca18d5fb2395c11cd3efb955e661f6036fa4c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:37:54 +0100 Subject: [PATCH 077/631] Add code stub for migrating signed int keys --- MIGRATING.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/MIGRATING.md b/MIGRATING.md index fca504b82..1d50e4809 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -208,6 +208,36 @@ As part of this, a couple helpers for handling int keys serialization and deseri You shouldn't need these, except when manually handling raw integer keys serialization / deserialization. +Migration code example: +```rust +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + let version = get_contract_version(deps.storage)?; + if version.contract != CONTRACT_NAME { + return Err(ContractError::CannotMigrate { + previous_contract: version.contract, + }); + } + // Original map + signed_int_map: Map = Map::new("signed_int_map"); + // New map + signed_int_map_new: Map = Map::new("signed_int_map-v2"); + + signed_int_map + .range_raw(deps.storage, None, None, Order::Ascending) + .map(|(k, v)| { + let signed = i8::from_be_bytes(k); + signed_int_map_new.save(deps.storage, signed, v); + }) + .collect()?; + + // Code to remove the old map keys + ... + + Ok(Response::default()) +} +``` + ### Non-breaking Issues / PRs - Deprecate `IntKey` [\#472](https://github.com/CosmWasm/cw-plus/issues/472) / From 61edf31db4a14cc58b4103565975e4064ab6c581 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:41:32 +0100 Subject: [PATCH 078/631] Clarify / simplify comments :-) --- MIGRATING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index 1d50e4809..84b736303 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -70,9 +70,9 @@ index 48a60083..2f2ef70d 100644 fn query_voter(deps: Deps, voter: String) -> StdResult { ``` -If / when you don't need key deserialization, just can just rename `range` to `range_raw` and you are good to go. +If you don't need key deserialization, just can just rename `range` to `range_raw` and you are good to go. -If you need / want key deserialization for **indexes**, you need to specify the primary key type as a last (optional) +If you want key deserialization for **indexes**, you need to specify the primary key type as a last (optional) argument in the index key specification. If not specified, it defaults to `()`, which means that primary keys will not only not be deserialized, but also not provided. This is for backwards-compatibility with current indexes specifications, and may change in the future once these features are stabilized. From 799ee37225f89f1f9466a102b2dc8cc8f7cdb191 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:46:47 +0100 Subject: [PATCH 079/631] Simplify range migration example --- MIGRATING.md | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index 84b736303..dbcaf802f 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -41,14 +41,7 @@ index 48a60083..2f2ef70d 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -385,21 +384,20 @@ fn list_votes( - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); - -- let votes: StdResult> = BALLOTS -+ let votes = BALLOTS - .prefix(proposal_id) -- .range_raw(deps.storage, start, None, Order::Ascending) -+ .range(deps.storage, start, None, Order::Ascending) + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - let (key, ballot) = item?; @@ -59,15 +52,6 @@ index 48a60083..2f2ef70d 100644 vote: ballot.vote, weight: ballot.weight, }) - }) -- .collect(); -+ .collect::>()?; - -- Ok(VoteListResponse { votes: votes? }) -+ Ok(VoteListResponse { votes }) - } - - fn query_voter(deps: Deps, voter: String) -> StdResult { ``` If you don't need key deserialization, just can just rename `range` to `range_raw` and you are good to go. From 4513ae26aa97889b89452de59f85d35da4e73efb Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:49:50 +0100 Subject: [PATCH 080/631] Simplify list of renames --- MIGRATING.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index dbcaf802f..e7f10f35e 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -62,8 +62,13 @@ not only not be deserialized, but also not provided. This is for backwards-compa specifications, and may change in the future once these features are stabilized. See `packages/storage-plus/src/indexed_map.rs` tests for reference. -Also, as part of this issue, `keys` was renamed to `keys_raw`, and `keys_de` to `keys`. `prefix_range` was also renamed, -to `prefix_range_raw`, and its key deserialization counterpart (`prefix_range_de`) to `prefix_range` in turn. +Renamed methods: +- `range` -> `range_raw` +- `keys` -> `keys_raw` +- `prefix_range` -> `prefix_range_raw` +- `range_de` -> `range` +- `keys_de` -> `keys` +- `prefix_range_de` -> `prefix_range` Finally, this applies to all the `Map`-like types, including indexed maps. From 33c49211c766680eb6d9743a54dd80c138a52ad1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 10:50:33 +0100 Subject: [PATCH 081/631] Rename to type params for correctness --- MIGRATING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATING.md b/MIGRATING.md index e7f10f35e..551082fca 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -152,7 +152,7 @@ index 022a4504..c7a3bb9d 100644 struct DataIndexes<'a> { - // Second arg is for storing pk - pub name: MultiIndex<'a, (String, String), Data, String>, -+ // Last args are for signaling pk deserialization ++ // Last type parameters are for signaling pk deserialization + pub name: MultiIndex<'a, String, Data, String>, pub age: UniqueIndex<'a, u32, Data, String>, pub name_lastname: UniqueIndex<'a, (Vec, Vec), Data, String>, From d91d83794d86444ca60ab340bba2d01e888fe6d2 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 21 Dec 2021 17:15:34 +0100 Subject: [PATCH 082/631] Move Threshold and coexisting implementations into packages/utils --- contracts/cw3-fixed-multisig/src/contract.rs | 6 +- contracts/cw3-flex-multisig/src/contract.rs | 19 +- contracts/cw3-flex-multisig/src/error.rs | 18 +- contracts/cw3-flex-multisig/src/msg.rs | 253 +------------- contracts/cw3-flex-multisig/src/state.rs | 4 +- packages/cw3/examples/schema.rs | 5 +- packages/cw3/src/lib.rs | 12 +- packages/cw3/src/query.rs | 73 +--- packages/utils/src/lib.rs | 2 + packages/utils/src/threshold.rs | 341 +++++++++++++++++++ 10 files changed, 373 insertions(+), 360 deletions(-) create mode 100644 packages/utils/src/threshold.rs diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 2f2ef70d5..ece844dc0 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -9,11 +9,11 @@ use cosmwasm_std::{ use cw2::set_contract_version; use cw3::{ - ProposalListResponse, ProposalResponse, Status, ThresholdResponse, Vote, VoteInfo, - VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, + ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, + VoterDetail, VoterListResponse, VoterResponse, }; use cw_storage_plus::Bound; -use utils::Expiration; +use utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 38169b6b5..d870652c5 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -9,12 +9,12 @@ use cosmwasm_std::{ use cw2::set_contract_version; use cw3::{ - ProposalListResponse, ProposalResponse, Status, ThresholdResponse, Vote, VoteInfo, - VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, + ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, + VoterDetail, VoterListResponse, VoterResponse, }; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; -use utils::{maybe_addr, Expiration}; +use utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -431,10 +431,9 @@ mod tests { use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; use cw_multi_test::{next_block, App, AppBuilder, Contract, ContractWrapper, Executor}; - use utils::Duration; + use utils::{Duration, Threshold}; use super::*; - use crate::msg::Threshold; const OWNER: &str = "admin0001"; const VOTER1: &str = "voter0001"; @@ -625,7 +624,10 @@ mod tests { None, ) .unwrap_err(); - assert_eq!(ContractError::InvalidThreshold {}, err.downcast().unwrap()); + assert_eq!( + ContractError::Threshold(utils::ThresholdError::InvalidThreshold {}), + err.downcast().unwrap() + ); // Total weight less than required weight not allowed let instantiate_msg = InstantiateMsg { @@ -643,7 +645,10 @@ mod tests { None, ) .unwrap_err(); - assert_eq!(ContractError::UnreachableWeight {}, err.downcast().unwrap()); + assert_eq!( + ContractError::Threshold(utils::ThresholdError::UnreachableWeight {}), + err.downcast().unwrap() + ); // All valid let instantiate_msg = InstantiateMsg { diff --git a/contracts/cw3-flex-multisig/src/error.rs b/contracts/cw3-flex-multisig/src/error.rs index 0c104222a..4a56312bb 100644 --- a/contracts/cw3-flex-multisig/src/error.rs +++ b/contracts/cw3-flex-multisig/src/error.rs @@ -1,4 +1,6 @@ use cosmwasm_std::StdError; +use utils::ThresholdError; + use thiserror::Error; #[derive(Error, Debug, PartialEq)] @@ -6,20 +8,8 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("Invalid voting threshold percentage, must be in the 0.5-1.0 range")] - InvalidThreshold {}, - - #[error("Required quorum threshold cannot be zero")] - ZeroQuorumThreshold {}, - - #[error("Not possible to reach required quorum threshold")] - UnreachableQuorumThreshold {}, - - #[error("Required weight cannot be zero")] - ZeroWeight {}, - - #[error("Not possible to reach required (passing) weight")] - UnreachableWeight {}, + #[error("{0}")] + Threshold(#[from] ThresholdError), #[error("Group contract invalid address '{addr}'")] InvalidGroup { addr: String }, diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 1bb2301d4..9b6fa67ef 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -1,11 +1,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::error::ContractError; -use cosmwasm_std::{CosmosMsg, Decimal, Empty}; -use cw3::{ThresholdResponse, Vote}; +use cosmwasm_std::{CosmosMsg, Empty}; +use cw3::Vote; use cw4::MemberChangedHookMsg; -use utils::{Duration, Expiration}; +use utils::{Duration, Expiration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { @@ -15,102 +14,6 @@ pub struct InstantiateMsg { pub max_voting_period: Duration, } -/// This defines the different ways tallies can happen. -/// -/// The total_weight used for calculating success as well as the weights of each -/// individual voter used in tallying should be snapshotted at the beginning of -/// the block at which the proposal starts (this is likely the responsibility of a -/// correct cw4 implementation). -/// See also `ThresholdResponse` in the cw3 spec. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum Threshold { - /// Declares that a fixed weight of Yes votes is needed to pass. - /// See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details. - AbsoluteCount { weight: u64 }, - - /// Declares a percentage of the total weight that must cast Yes votes in order for - /// a proposal to pass. - /// See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details. - AbsolutePercentage { percentage: Decimal }, - - /// Declares a `quorum` of the total votes that must participate in the election in order - /// for the vote to be considered at all. - /// See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details. - ThresholdQuorum { threshold: Decimal, quorum: Decimal }, -} - -impl Threshold { - /// returns error if this is an unreachable value, - /// given a total weight of all members in the group - pub fn validate(&self, total_weight: u64) -> Result<(), ContractError> { - match self { - Threshold::AbsoluteCount { - weight: weight_needed, - } => { - if *weight_needed == 0 { - Err(ContractError::ZeroWeight {}) - } else if *weight_needed > total_weight { - Err(ContractError::UnreachableWeight {}) - } else { - Ok(()) - } - } - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => valid_threshold(percentage_needed), - Threshold::ThresholdQuorum { - threshold, - quorum: quroum, - } => { - valid_threshold(threshold)?; - valid_quorum(quroum) - } - } - } - - /// Creates a response from the saved data, just missing the total_weight info - pub fn to_response(&self, total_weight: u64) -> ThresholdResponse { - match self.clone() { - Threshold::AbsoluteCount { weight } => ThresholdResponse::AbsoluteCount { - weight, - total_weight, - }, - Threshold::AbsolutePercentage { percentage } => ThresholdResponse::AbsolutePercentage { - percentage, - total_weight, - }, - Threshold::ThresholdQuorum { threshold, quorum } => { - ThresholdResponse::ThresholdQuorum { - threshold, - quorum, - total_weight, - } - } - } - } -} - -/// Asserts that the 0.5 < percent <= 1.0 -fn valid_threshold(percent: &Decimal) -> Result<(), ContractError> { - if *percent > Decimal::percent(100) || *percent < Decimal::percent(50) { - Err(ContractError::InvalidThreshold {}) - } else { - Ok(()) - } -} - -/// Asserts that the 0.5 < percent <= 1.0 -fn valid_quorum(percent: &Decimal) -> Result<(), ContractError> { - if percent.is_zero() { - Err(ContractError::ZeroQuorumThreshold {}) - } else if *percent > Decimal::one() { - Err(ContractError::UnreachableQuorumThreshold {}) - } else { - Ok(()) - } -} - // TODO: add some T variants? Maybe good enough as fixed Empty for now #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -170,153 +73,3 @@ pub enum QueryMsg { limit: Option, }, } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn validate_quorum_percentage() { - // TODO: test the error messages - - // 0 is never a valid percentage - let err = valid_quorum(&Decimal::zero()).unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::ZeroQuorumThreshold {}.to_string() - ); - - // 100% is - valid_quorum(&Decimal::one()).unwrap(); - - // 101% is not - let err = valid_quorum(&Decimal::percent(101)).unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::UnreachableQuorumThreshold {}.to_string() - ); - // not 100.1% - let err = valid_quorum(&Decimal::permille(1001)).unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::UnreachableQuorumThreshold {}.to_string() - ); - } - - #[test] - fn validate_threshold_percentage() { - // other values in between 0.5 and 1 are valid - valid_threshold(&Decimal::percent(51)).unwrap(); - valid_threshold(&Decimal::percent(67)).unwrap(); - valid_threshold(&Decimal::percent(99)).unwrap(); - let err = valid_threshold(&Decimal::percent(101)).unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::InvalidThreshold {}.to_string() - ); - } - - #[test] - fn validate_threshold() { - // absolute count ensures 0 < required <= total_weight - let err = Threshold::AbsoluteCount { weight: 0 } - .validate(5) - .unwrap_err(); - // TODO: remove to_string() when PartialEq implemented - assert_eq!(err.to_string(), ContractError::ZeroWeight {}.to_string()); - let err = Threshold::AbsoluteCount { weight: 6 } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::UnreachableWeight {}.to_string() - ); - - Threshold::AbsoluteCount { weight: 1 }.validate(5).unwrap(); - Threshold::AbsoluteCount { weight: 5 }.validate(5).unwrap(); - - // AbsolutePercentage just enforces valid_percentage (tested above) - let err = Threshold::AbsolutePercentage { - percentage: Decimal::zero(), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::InvalidThreshold {}.to_string() - ); - Threshold::AbsolutePercentage { - percentage: Decimal::percent(51), - } - .validate(5) - .unwrap(); - - // Quorum enforces both valid just enforces valid_percentage (tested above) - Threshold::ThresholdQuorum { - threshold: Decimal::percent(51), - quorum: Decimal::percent(40), - } - .validate(5) - .unwrap(); - let err = Threshold::ThresholdQuorum { - threshold: Decimal::percent(101), - quorum: Decimal::percent(40), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::InvalidThreshold {}.to_string() - ); - let err = Threshold::ThresholdQuorum { - threshold: Decimal::percent(51), - quorum: Decimal::percent(0), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ContractError::ZeroQuorumThreshold {}.to_string() - ); - } - - #[test] - fn threshold_response() { - let total_weight: u64 = 100; - - let res = Threshold::AbsoluteCount { weight: 42 }.to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::AbsoluteCount { - weight: 42, - total_weight - } - ); - - let res = Threshold::AbsolutePercentage { - percentage: Decimal::percent(51), - } - .to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::AbsolutePercentage { - percentage: Decimal::percent(51), - total_weight - } - ); - - let res = Threshold::ThresholdQuorum { - threshold: Decimal::percent(66), - quorum: Decimal::percent(50), - } - .to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::ThresholdQuorum { - threshold: Decimal::percent(66), - quorum: Decimal::percent(50), - total_weight - } - ); - } -} diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 013757beb..59b1518b4 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -6,9 +6,7 @@ use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storag use cw3::{Status, Vote}; use cw4::Cw4Contract; use cw_storage_plus::{Item, Map}; -use utils::{Duration, Expiration}; - -use crate::msg::Threshold; +use utils::{Duration, Expiration, Threshold}; // we multiply by this when calculating needed_votes in order to round up properly // Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" diff --git a/packages/cw3/examples/schema.rs b/packages/cw3/examples/schema.rs index 2cbd5f59b..53329e81e 100644 --- a/packages/cw3/examples/schema.rs +++ b/packages/cw3/examples/schema.rs @@ -4,9 +4,10 @@ use std::fs::create_dir_all; use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; use cw3::{ - Cw3ExecuteMsg, Cw3QueryMsg, ProposalListResponse, ProposalResponse, ThresholdResponse, - VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, + Cw3ExecuteMsg, Cw3QueryMsg, ProposalListResponse, ProposalResponse, VoteListResponse, + VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; +use utils::ThresholdResponse; fn main() { let mut out_dir = current_dir().unwrap(); diff --git a/packages/cw3/src/lib.rs b/packages/cw3/src/lib.rs index 307bea09a..bda9d2d93 100644 --- a/packages/cw3/src/lib.rs +++ b/packages/cw3/src/lib.rs @@ -6,14 +6,6 @@ mod query; pub use crate::helpers::Cw3Contract; pub use crate::msg::{Cw3ExecuteMsg, Vote}; pub use crate::query::{ - Cw3QueryMsg, ProposalListResponse, ProposalResponse, Status, ThresholdResponse, VoteInfo, - VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, + Cw3QueryMsg, ProposalListResponse, ProposalResponse, Status, VoteInfo, VoteListResponse, + VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - // test me - } -} diff --git a/packages/cw3/src/query.rs b/packages/cw3/src/query.rs index 5cfd17189..ea28e918e 100644 --- a/packages/cw3/src/query.rs +++ b/packages/cw3/src/query.rs @@ -2,8 +2,8 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt; -use cosmwasm_std::{CosmosMsg, Decimal, Empty}; -use utils::Expiration; +use cosmwasm_std::{CosmosMsg, Empty}; +use utils::{Expiration, ThresholdResponse}; use crate::msg::Vote; @@ -49,75 +49,6 @@ pub enum Cw3QueryMsg { }, } -/// This defines the different ways tallies can happen. -/// Every contract should support a subset of these, ideally all. -/// -/// The total_weight used for calculating success as well as the weights of each -/// individual voter used in tallying should be snapshotted at the beginning of -/// the block at which the proposal starts (this is likely the responsibility of a -/// correct cw4 implementation). -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum ThresholdResponse { - /// Declares that a fixed weight of yes votes is needed to pass. - /// It does not matter how many no votes are cast, or how many do not vote, - /// as long as `weight` yes votes are cast. - /// - /// This is the simplest format and usually suitable for small multisigs of trusted parties, - /// like 3 of 5. (weight: 3, total_weight: 5) - /// - /// A proposal of this type can pass early as soon as the needed weight of yes votes has been cast. - AbsoluteCount { weight: u64, total_weight: u64 }, - - /// Declares a percentage of the total weight that must cast Yes votes, in order for - /// a proposal to pass. The passing weight is computed over the total weight minus the weight of the - /// abstained votes. - /// - /// This is useful for similar circumstances as `AbsoluteCount`, where we have a relatively - /// small set of voters, and participation is required. - /// It is understood that if the voting set (group) changes between different proposals that - /// refer to the same group, each proposal will work with a different set of voter weights - /// (the ones snapshotted at proposal creation), and the passing weight for each proposal - /// will be computed based on the absolute percentage, times the total weights of the members - /// at the time of each proposal creation. - /// - /// Example: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. - /// This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the - /// `total_weight` of the group has increased to 9. That proposal will then automatically - /// require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`. - AbsolutePercentage { - percentage: Decimal, - total_weight: u64, - }, - - /// In addition to a `threshold`, declares a `quorum` of the total votes that must participate - /// in the election in order for the vote to be considered at all. Within the votes that - /// were cast, it requires `threshold` votes in favor. That is calculated by ignoring - /// the Abstain votes (they count towards `quorum`, but do not influence `threshold`). - /// That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider - /// if the proposal was passed. - /// - /// It is rather difficult for a proposal of this type to pass early. That can only happen if - /// the required quorum has been already met, and there are already enough Yes votes for the - /// proposal to pass. - /// - /// 30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% - /// (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting - /// no => 30% yes + 50% no). Once the voting period has passed with no additional votes, - /// that same proposal would be considered successful if quorum <= 60% and threshold <= 75% - /// (percent in favor if we ignore abstain votes). - /// - /// This type is more common in general elections, where participation is often expected to - /// be low, and `AbsolutePercentage` would either be too high to pass anything, - /// or allow low percentages to pass, independently of if there was high participation in the - /// election or not. - ThresholdQuorum { - threshold: Decimal, - quorum: Decimal, - total_weight: u64, - }, -} - /// Note, if you are storing custom messages in the proposal, /// the querier needs to know what possible custom message types /// those are in order to parse the response diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index 939599c00..c39b1005e 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -4,6 +4,7 @@ mod expiration; mod pagination; mod parse_reply; mod payment; +mod threshold; pub use pagination::{ calc_range_end, calc_range_start, calc_range_start_string, maybe_addr, maybe_canonical, @@ -14,6 +15,7 @@ pub use parse_reply::{ ParseReplyError, }; pub use payment::{may_pay, must_pay, nonpayable, one_coin, PaymentError}; +pub use threshold::{Threshold, ThresholdError, ThresholdResponse}; pub use crate::balance::NativeBalance; pub use crate::event::Event; diff --git a/packages/utils/src/threshold.rs b/packages/utils/src/threshold.rs new file mode 100644 index 000000000..b919f7a02 --- /dev/null +++ b/packages/utils/src/threshold.rs @@ -0,0 +1,341 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{Decimal, StdError}; +use thiserror::Error; + +/// This defines the different ways tallies can happen. +/// +/// The total_weight used for calculating success as well as the weights of each +/// individual voter used in tallying should be snapshotted at the beginning of +/// the block at which the proposal starts (this is likely the responsibility of a +/// correct cw4 implementation). +/// See also `ThresholdResponse` in the cw3 spec. +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[serde(rename_all = "snake_case")] +pub enum Threshold { + /// Declares that a fixed weight of Yes votes is needed to pass. + /// See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details. + AbsoluteCount { weight: u64 }, + + /// Declares a percentage of the total weight that must cast Yes votes in order for + /// a proposal to pass. + /// See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details. + AbsolutePercentage { percentage: Decimal }, + + /// Declares a `quorum` of the total votes that must participate in the election in order + /// for the vote to be considered at all. + /// See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details. + ThresholdQuorum { threshold: Decimal, quorum: Decimal }, +} + +impl Threshold { + /// returns error if this is an unreachable value, + /// given a total weight of all members in the group + pub fn validate(&self, total_weight: u64) -> Result<(), ThresholdError> { + match self { + Threshold::AbsoluteCount { + weight: weight_needed, + } => { + if *weight_needed == 0 { + Err(ThresholdError::ZeroWeight {}) + } else if *weight_needed > total_weight { + Err(ThresholdError::UnreachableWeight {}) + } else { + Ok(()) + } + } + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => valid_threshold(percentage_needed), + Threshold::ThresholdQuorum { + threshold, + quorum: quroum, + } => { + valid_threshold(threshold)?; + valid_quorum(quroum) + } + } + } + + /// Creates a response from the saved data, just missing the total_weight info + pub fn to_response(&self, total_weight: u64) -> ThresholdResponse { + match self.clone() { + Threshold::AbsoluteCount { weight } => ThresholdResponse::AbsoluteCount { + weight, + total_weight, + }, + Threshold::AbsolutePercentage { percentage } => ThresholdResponse::AbsolutePercentage { + percentage, + total_weight, + }, + Threshold::ThresholdQuorum { threshold, quorum } => { + ThresholdResponse::ThresholdQuorum { + threshold, + quorum, + total_weight, + } + } + } + } +} + +/// Asserts that the 0.5 < percent <= 1.0 +fn valid_threshold(percent: &Decimal) -> Result<(), ThresholdError> { + if *percent > Decimal::percent(100) || *percent < Decimal::percent(50) { + Err(ThresholdError::InvalidThreshold {}) + } else { + Ok(()) + } +} + +/// Asserts that the 0.5 < percent <= 1.0 +fn valid_quorum(percent: &Decimal) -> Result<(), ThresholdError> { + if percent.is_zero() { + Err(ThresholdError::ZeroQuorumThreshold {}) + } else if *percent > Decimal::one() { + Err(ThresholdError::UnreachableQuorumThreshold {}) + } else { + Ok(()) + } +} + +/// This defines the different ways tallies can happen. +/// Every contract should support a subset of these, ideally all. +/// +/// The total_weight used for calculating success as well as the weights of each +/// individual voter used in tallying should be snapshotted at the beginning of +/// the block at which the proposal starts (this is likely the responsibility of a +/// correct cw4 implementation). +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[serde(rename_all = "snake_case")] +pub enum ThresholdResponse { + /// Declares that a fixed weight of yes votes is needed to pass. + /// It does not matter how many no votes are cast, or how many do not vote, + /// as long as `weight` yes votes are cast. + /// + /// This is the simplest format and usually suitable for small multisigs of trusted parties, + /// like 3 of 5. (weight: 3, total_weight: 5) + /// + /// A proposal of this type can pass early as soon as the needed weight of yes votes has been cast. + AbsoluteCount { weight: u64, total_weight: u64 }, + + /// Declares a percentage of the total weight that must cast Yes votes, in order for + /// a proposal to pass. The passing weight is computed over the total weight minus the weight of the + /// abstained votes. + /// + /// This is useful for similar circumstances as `AbsoluteCount`, where we have a relatively + /// small set of voters, and participation is required. + /// It is understood that if the voting set (group) changes between different proposals that + /// refer to the same group, each proposal will work with a different set of voter weights + /// (the ones snapshotted at proposal creation), and the passing weight for each proposal + /// will be computed based on the absolute percentage, times the total weights of the members + /// at the time of each proposal creation. + /// + /// Example: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. + /// This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the + /// `total_weight` of the group has increased to 9. That proposal will then automatically + /// require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`. + AbsolutePercentage { + percentage: Decimal, + total_weight: u64, + }, + + /// In addition to a `threshold`, declares a `quorum` of the total votes that must participate + /// in the election in order for the vote to be considered at all. Within the votes that + /// were cast, it requires `threshold` votes in favor. That is calculated by ignoring + /// the Abstain votes (they count towards `quorum`, but do not influence `threshold`). + /// That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider + /// if the proposal was passed. + /// + /// It is rather difficult for a proposal of this type to pass early. That can only happen if + /// the required quorum has been already met, and there are already enough Yes votes for the + /// proposal to pass. + /// + /// 30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% + /// (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting + /// no => 30% yes + 50% no). Once the voting period has passed with no additional votes, + /// that same proposal would be considered successful if quorum <= 60% and threshold <= 75% + /// (percent in favor if we ignore abstain votes). + /// + /// This type is more common in general elections, where participation is often expected to + /// be low, and `AbsolutePercentage` would either be too high to pass anything, + /// or allow low percentages to pass, independently of if there was high participation in the + /// election or not. + ThresholdQuorum { + threshold: Decimal, + quorum: Decimal, + total_weight: u64, + }, +} + +#[derive(Error, Debug, PartialEq)] +pub enum ThresholdError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Invalid voting threshold percentage, must be in the 0.5-1.0 range")] + InvalidThreshold {}, + + #[error("Required quorum threshold cannot be zero")] + ZeroQuorumThreshold {}, + + #[error("Not possible to reach required quorum threshold")] + UnreachableQuorumThreshold {}, + + #[error("Required weight cannot be zero")] + ZeroWeight {}, + + #[error("Not possible to reach required (passing) weight")] + UnreachableWeight {}, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn validate_quorum_percentage() { + // TODO: test the error messages + + // 0 is never a valid percentage + let err = valid_quorum(&Decimal::zero()).unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::ZeroQuorumThreshold {}.to_string() + ); + + // 100% is + valid_quorum(&Decimal::one()).unwrap(); + + // 101% is not + let err = valid_quorum(&Decimal::percent(101)).unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::UnreachableQuorumThreshold {}.to_string() + ); + // not 100.1% + let err = valid_quorum(&Decimal::permille(1001)).unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::UnreachableQuorumThreshold {}.to_string() + ); + } + + #[test] + fn validate_threshold_percentage() { + // other values in between 0.5 and 1 are valid + valid_threshold(&Decimal::percent(51)).unwrap(); + valid_threshold(&Decimal::percent(67)).unwrap(); + valid_threshold(&Decimal::percent(99)).unwrap(); + let err = valid_threshold(&Decimal::percent(101)).unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::InvalidThreshold {}.to_string() + ); + } + + #[test] + fn validate_threshold() { + // absolute count ensures 0 < required <= total_weight + let err = Threshold::AbsoluteCount { weight: 0 } + .validate(5) + .unwrap_err(); + // TODO: remove to_string() when PartialEq implemented + assert_eq!(err.to_string(), ThresholdError::ZeroWeight {}.to_string()); + let err = Threshold::AbsoluteCount { weight: 6 } + .validate(5) + .unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::UnreachableWeight {}.to_string() + ); + + Threshold::AbsoluteCount { weight: 1 }.validate(5).unwrap(); + Threshold::AbsoluteCount { weight: 5 }.validate(5).unwrap(); + + // AbsolutePercentage just enforces valid_percentage (tested above) + let err = Threshold::AbsolutePercentage { + percentage: Decimal::zero(), + } + .validate(5) + .unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::InvalidThreshold {}.to_string() + ); + Threshold::AbsolutePercentage { + percentage: Decimal::percent(51), + } + .validate(5) + .unwrap(); + + // Quorum enforces both valid just enforces valid_percentage (tested above) + Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(40), + } + .validate(5) + .unwrap(); + let err = Threshold::ThresholdQuorum { + threshold: Decimal::percent(101), + quorum: Decimal::percent(40), + } + .validate(5) + .unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::InvalidThreshold {}.to_string() + ); + let err = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(0), + } + .validate(5) + .unwrap_err(); + assert_eq!( + err.to_string(), + ThresholdError::ZeroQuorumThreshold {}.to_string() + ); + } + + #[test] + fn threshold_response() { + let total_weight: u64 = 100; + + let res = Threshold::AbsoluteCount { weight: 42 }.to_response(total_weight); + assert_eq!( + res, + ThresholdResponse::AbsoluteCount { + weight: 42, + total_weight + } + ); + + let res = Threshold::AbsolutePercentage { + percentage: Decimal::percent(51), + } + .to_response(total_weight); + assert_eq!( + res, + ThresholdResponse::AbsolutePercentage { + percentage: Decimal::percent(51), + total_weight + } + ); + + let res = Threshold::ThresholdQuorum { + threshold: Decimal::percent(66), + quorum: Decimal::percent(50), + } + .to_response(total_weight); + assert_eq!( + res, + ThresholdResponse::ThresholdQuorum { + threshold: Decimal::percent(66), + quorum: Decimal::percent(50), + total_weight + } + ); + } +} From 1b43516fb06e875919e8fbad9fdd92d727f3cdf6 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 21 Dec 2021 14:05:32 +0100 Subject: [PATCH 083/631] cw3-fixed-multisig: require >=1 weight for proposing and voting --- contracts/cw3-fixed-multisig/src/contract.rs | 70 +++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index ece844dc0..b2eba9c25 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -89,10 +89,12 @@ pub fn execute_propose( // we ignore earliest latest: Option, ) -> Result, ContractError> { - // only members of the multisig can create a proposal - let vote_power = VOTERS - .may_load(deps.storage, &info.sender)? - .ok_or(ContractError::Unauthorized {})?; + // only members of the multisig with weight >= 1 can create a proposal + let voter_power = VOTERS.may_load(deps.storage, &info.sender)?; + let vote_power = match voter_power { + Some(power) if power >= 1 => power, + _ => return Err(ContractError::Unauthorized {}), + }; let cfg = CONFIG.load(deps.storage)?; @@ -146,10 +148,12 @@ pub fn execute_vote( proposal_id: u64, vote: Vote, ) -> Result, ContractError> { - // only members of the multisig can vote - let vote_power = VOTERS - .may_load(deps.storage, &info.sender)? - .ok_or(ContractError::Unauthorized {})?; + // only members of the multisig with weight >= 1 can vote + let voter_power = VOTERS.may_load(deps.storage, &info.sender)?; + let vote_power = match voter_power { + Some(power) if power >= 1 => power, + _ => return Err(ContractError::Unauthorized {}), + }; // ensure proposal exists and can be voted on let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; @@ -458,6 +462,7 @@ mod tests { const VOTER3: &str = "voter0003"; const VOTER4: &str = "voter0004"; const VOTER5: &str = "voter0005"; + const NOWEIGHT_VOTER: &str = "voterxxxx"; const SOMEBODY: &str = "somebody"; fn voter>(addr: T, weight: u64) -> Voter { @@ -468,6 +473,7 @@ mod tests { } // this will set up the instantiation for other tests + #[track_caller] fn setup_test_case( deps: DepsMut, info: MessageInfo, @@ -476,12 +482,13 @@ mod tests { ) -> Result, ContractError> { // Instantiate a contract with voters let voters = vec![ - voter(&info.sender, 0), + voter(&info.sender, 1), voter(VOTER1, 1), voter(VOTER2, 2), voter(VOTER3, 3), voter(VOTER4, 4), voter(VOTER5, 5), + voter(NOWEIGHT_VOTER, 0), ]; let instantiate_msg = InstantiateMsg { @@ -564,6 +571,51 @@ mod tests { // TODO: query() tests + #[test] + fn zero_weight_member_cant_propose_and_vote() { + let mut deps = mock_dependencies(); + + let required_weight = 4; + let voting_period = Duration::Time(2000000); + + let info = mock_info(OWNER, &[]); + setup_test_case(deps.as_mut(), info, required_weight, voting_period).unwrap(); + + let bank_msg = BankMsg::Send { + to_address: SOMEBODY.into(), + amount: vec![coin(1, "BTC")], + }; + let msgs = vec![CosmosMsg::Bank(bank_msg)]; + + // Only voters with weight can propose + let info = mock_info(NOWEIGHT_VOTER, &[]); + let proposal = ExecuteMsg::Propose { + title: "Rewarding somebody".to_string(), + description: "Do we reward her?".to_string(), + msgs, + latest: None, + }; + let err = execute(deps.as_mut(), mock_env(), info, proposal.clone()).unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); + + // Propose proposal + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), mock_env(), info, proposal).unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.attributes[2].value.parse().unwrap(); + + // Cast a No vote + let no_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::No, + }; + // Only voters with weight can vote + let info = mock_info(NOWEIGHT_VOTER, &[]); + execute(deps.as_mut(), mock_env(), info, no_vote).unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); + } + #[test] fn test_propose_works() { let mut deps = mock_dependencies(); From 0faeaf4aba9e1be0120db8ffc3cd8bfdea73d8fc Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 21 Dec 2021 15:17:54 +0100 Subject: [PATCH 084/631] cw3-fixed-multisig: reuse or copy most of existing implementation from cw3-flex-multisig --- Cargo.lock | 1 + contracts/cw3-fixed-multisig/Cargo.toml | 1 + contracts/cw3-fixed-multisig/src/contract.rs | 91 +++++++------------- contracts/cw3-fixed-multisig/src/error.rs | 4 + contracts/cw3-fixed-multisig/src/msg.rs | 3 +- contracts/cw3-fixed-multisig/src/state.rs | 54 +----------- contracts/cw3-flex-multisig/src/lib.rs | 2 +- 7 files changed, 42 insertions(+), 114 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43fed7b8b..bace81e43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,6 +530,7 @@ dependencies = [ "cw20", "cw20-base", "cw3", + "cw3-flex-multisig", "schemars", "serde", "thiserror", diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index edab67af4..5843d0ebe 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -21,6 +21,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } +cw3-flex-multisig = { path = "../cw3-flex-multisig", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index b2eba9c25..f37275010 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -12,12 +12,14 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; +use cw3_flex_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; + use cw_storage_plus::Bound; use utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{next_id, Ballot, Config, Proposal, BALLOTS, CONFIG, PROPOSALS, VOTERS}; +use crate::state::{Config, CONFIG, VOTERS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-fixed-multisig"; @@ -30,22 +32,17 @@ pub fn instantiate( _info: MessageInfo, msg: InstantiateMsg, ) -> Result { - if msg.required_weight == 0 { - return Err(ContractError::ZeroWeight {}); - } if msg.voters.is_empty() { return Err(ContractError::NoVoters {}); } let total_weight = msg.voters.iter().map(|v| v.weight).sum(); - if total_weight < msg.required_weight { - return Err(ContractError::UnreachableWeight {}); - } + msg.threshold.validate(total_weight)?; set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { - required_weight: msg.required_weight, + threshold: msg.threshold, total_weight, max_voting_period: msg.max_voting_period, }; @@ -89,12 +86,10 @@ pub fn execute_propose( // we ignore earliest latest: Option, ) -> Result, ContractError> { - // only members of the multisig with weight >= 1 can create a proposal - let voter_power = VOTERS.may_load(deps.storage, &info.sender)?; - let vote_power = match voter_power { - Some(power) if power >= 1 => power, - _ => return Err(ContractError::Unauthorized {}), - }; + // only members of the multisig can create a proposal + let vote_power = VOTERS + .may_load(deps.storage, &info.sender)? + .ok_or(ContractError::Unauthorized {})?; let cfg = CONFIG.load(deps.storage)?; @@ -108,22 +103,19 @@ pub fn execute_propose( return Err(ContractError::WrongExpiration {}); } - let status = if vote_power < cfg.required_weight { - Status::Open - } else { - Status::Passed - }; - // create a proposal - let prop = Proposal { + let mut prop = Proposal { title, description, + start_height: env.block.height, expires, msgs, - status, - yes_weight: vote_power, - required_weight: cfg.required_weight, + status: Status::Open, + votes: Votes::yes(vote_power), + threshold: cfg.threshold, + total_weight: cfg.total_weight, }; + prop.update_status(&env.block); let id = next_id(deps.storage)?; PROPOSALS.save(deps.storage, id, &prop)?; @@ -173,15 +165,10 @@ pub fn execute_vote( }), })?; - // if yes vote, update tally - if vote == Vote::Yes { - prop.yes_weight += vote_power; - // update status when the passing vote comes in - if prop.yes_weight >= prop.required_weight { - prop.status = Status::Passed; - } - PROPOSALS.save(deps.storage, proposal_id, &prop)?; - } + // update vote tally + prop.votes.add_vote(vote, vote_power); + prop.update_status(&env.block); + PROPOSALS.save(deps.storage, proposal_id, &prop)?; Ok(Response::new() .add_attribute("action", "vote") @@ -273,21 +260,13 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { fn query_threshold(deps: Deps) -> StdResult { let cfg = CONFIG.load(deps.storage)?; - Ok(ThresholdResponse::AbsoluteCount { - weight: cfg.required_weight, - total_weight: cfg.total_weight, - }) + Ok(cfg.threshold.to_response(cfg.total_weight)) } fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult { let prop = PROPOSALS.load(deps.storage, id)?; let status = prop.current_status(&env.block); - - let cfg = CONFIG.load(deps.storage)?; - let threshold = ThresholdResponse::AbsoluteCount { - weight: cfg.required_weight, - total_weight: cfg.total_weight, - }; + let threshold = prop.threshold.to_response(prop.total_weight); Ok(ProposalResponse { id, title: prop.title, @@ -309,18 +288,12 @@ fn list_proposals( start_after: Option, limit: Option, ) -> StdResult { - let cfg = CONFIG.load(deps.storage)?; - let threshold = ThresholdResponse::AbsoluteCount { - weight: cfg.required_weight, - total_weight: cfg.total_weight, - }; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(Bound::exclusive_int); let proposals = PROPOSALS .range(deps.storage, start, None, Order::Ascending) .take(limit) - .map(|p| map_proposal(&env.block, &threshold, p)) + .map(|p| map_proposal(&env.block, p)) .collect::>()?; Ok(ProposalListResponse { proposals }) @@ -332,30 +305,24 @@ fn reverse_proposals( start_before: Option, limit: Option, ) -> StdResult { - let cfg = CONFIG.load(deps.storage)?; - let threshold = ThresholdResponse::AbsoluteCount { - weight: cfg.required_weight, - total_weight: cfg.total_weight, - }; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let end = start_before.map(Bound::exclusive_int); - let proposals = PROPOSALS + let props: StdResult> = PROPOSALS .range(deps.storage, None, end, Order::Descending) .take(limit) - .map(|p| map_proposal(&env.block, &threshold, p)) - .collect::>()?; + .map(|p| map_proposal(&env.block, p)) + .collect(); - Ok(ProposalListResponse { proposals }) + Ok(ProposalListResponse { proposals: props? }) } fn map_proposal( block: &BlockInfo, - threshold: &ThresholdResponse, item: StdResult<(u64, Proposal)>, ) -> StdResult { item.map(|(id, prop)| { let status = prop.current_status(block); + let threshold = prop.threshold.to_response(prop.total_weight); ProposalResponse { id, title: prop.title, @@ -363,7 +330,7 @@ fn map_proposal( msgs: prop.msgs, status, expires: prop.expires, - threshold: threshold.clone(), + threshold, } }) } diff --git a/contracts/cw3-fixed-multisig/src/error.rs b/contracts/cw3-fixed-multisig/src/error.rs index 78e0eb036..83ab07362 100644 --- a/contracts/cw3-fixed-multisig/src/error.rs +++ b/contracts/cw3-fixed-multisig/src/error.rs @@ -1,4 +1,5 @@ use cosmwasm_std::StdError; +use cw3_flex_multisig::error::ContractError as Cw3FlexMultisigError; use thiserror::Error; #[derive(Error, Debug, PartialEq)] @@ -6,6 +7,9 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), + #[error("{0}")] + FlexMultisig(#[from] Cw3FlexMultisigError), + #[error("Required weight cannot be zero")] ZeroWeight {}, diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index 41aae35eb..81ed7801a 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -3,12 +3,13 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; +use cw3_flex_multisig::msg::Threshold; use utils::{Duration, Expiration}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { pub voters: Vec, - pub required_weight: u64, + pub threshold: Threshold, pub max_voting_period: Duration, } diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index b596ef605..27e2d2801 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -1,67 +1,21 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Empty, StdResult, Storage}; - -use cw3::{Status, Vote}; +use cosmwasm_std::Addr; +use cw3_flex_multisig::msg::Threshold; use cw_storage_plus::{Item, Map}; -use utils::{Duration, Expiration}; +use utils::Duration; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { - pub required_weight: u64, + pub threshold: Threshold, pub total_weight: u64, pub max_voting_period: Duration, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Proposal { - pub title: String, - pub description: String, - pub expires: Expiration, - pub msgs: Vec>, - pub status: Status, - /// how many votes have already said yes - pub yes_weight: u64, - /// how many votes needed to pass - pub required_weight: u64, -} - -impl Proposal { - pub fn current_status(&self, block: &BlockInfo) -> Status { - let mut status = self.status; - - // if open, check if voting is passed or timed out - if status == Status::Open && self.yes_weight >= self.required_weight { - status = Status::Passed; - } - if status == Status::Open && self.expires.is_expired(block) { - status = Status::Rejected; - } - - status - } -} - -// we cast a ballot with our chosen vote and a given weight -// stored under the key that voted -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Ballot { - pub weight: u64, - pub vote: Vote, -} - // unique items pub const CONFIG: Item = Item::new("config"); pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); // multiple-item maps pub const VOTERS: Map<&Addr, u64> = Map::new("voters"); -pub const PROPOSALS: Map = Map::new("proposals"); -pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("ballots"); - -pub fn next_id(store: &mut dyn Storage) -> StdResult { - let id: u64 = PROPOSAL_COUNT.may_load(store)?.unwrap_or_default() + 1; - PROPOSAL_COUNT.save(store, &id)?; - Ok(id) -} diff --git a/contracts/cw3-flex-multisig/src/lib.rs b/contracts/cw3-flex-multisig/src/lib.rs index dfedc9dc6..e5ff7237e 100644 --- a/contracts/cw3-flex-multisig/src/lib.rs +++ b/contracts/cw3-flex-multisig/src/lib.rs @@ -1,5 +1,5 @@ pub mod contract; -mod error; +pub mod error; pub mod msg; pub mod state; From 2942b8a1c1908463abe887a9263b6f5bd54fa333 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 21 Dec 2021 15:44:50 +0100 Subject: [PATCH 085/631] cw3-fixed-multisig: adapt tests so that now quorum is checked --- contracts/cw3-fixed-multisig/src/contract.rs | 76 +++++++++---------- .../src/integration_tests.rs | 8 +- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index f37275010..9097e37ad 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -402,9 +402,10 @@ fn list_voters( #[cfg(test)] mod tests { use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coin, from_binary, BankMsg}; + use cosmwasm_std::{coin, from_binary, BankMsg, Decimal}; use cw2::{get_contract_version, ContractVersion}; + use cw3_flex_multisig::msg::Threshold; use utils::Duration; use crate::msg::Voter; @@ -444,7 +445,7 @@ mod tests { fn setup_test_case( deps: DepsMut, info: MessageInfo, - required_weight: u64, + threshold: Threshold, max_voting_period: Duration, ) -> Result, ContractError> { // Instantiate a contract with voters @@ -460,7 +461,7 @@ mod tests { let instantiate_msg = InstantiateMsg { voters, - required_weight, + threshold, max_voting_period, }; instantiate(deps, mock_env(), info, instantiate_msg) @@ -494,37 +495,41 @@ mod tests { // No voters fails let instantiate_msg = InstantiateMsg { voters: vec![], - required_weight: 1, + threshold: Threshold::ThresholdQuorum { + threshold: Decimal::zero(), + quorum: Decimal::percent(1), + }, max_voting_period, }; - let err = - instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap_err(); + let err = instantiate( + deps.as_mut(), + mock_env(), + info.clone(), + instantiate_msg.clone(), + ) + .unwrap_err(); assert_eq!(err, ContractError::NoVoters {}); // Zero required weight fails let instantiate_msg = InstantiateMsg { voters: vec![voter(OWNER, 1)], - required_weight: 0, - max_voting_period, + ..instantiate_msg }; let err = instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap_err(); - assert_eq!(err, ContractError::ZeroWeight {}); + + use cw3_flex_multisig::ContractError::{InvalidThreshold, UnreachableWeight}; + assert_eq!(err, ContractError::FlexMultisig(InvalidThreshold {})); // Total weight less than required weight not allowed - let required_weight = 100; - let err = setup_test_case( - deps.as_mut(), - info.clone(), - required_weight, - max_voting_period, - ) - .unwrap_err(); - assert_eq!(err, ContractError::UnreachableWeight {}); + let threshold = Threshold::AbsoluteCount { weight: 100 }; + let err = + setup_test_case(deps.as_mut(), info.clone(), threshold, max_voting_period).unwrap_err(); + assert_eq!(err, ContractError::FlexMultisig(UnreachableWeight {})); // All valid - let required_weight = 1; - setup_test_case(deps.as_mut(), info, required_weight, max_voting_period).unwrap(); + let threshold = Threshold::AbsoluteCount { weight: 1 }; + setup_test_case(deps.as_mut(), info, threshold, max_voting_period).unwrap(); // Verify assert_eq!( @@ -539,14 +544,14 @@ mod tests { // TODO: query() tests #[test] - fn zero_weight_member_cant_propose_and_vote() { + fn zero_weight_member_cant_vote() { let mut deps = mock_dependencies(); - let required_weight = 4; + let threshold = Threshold::AbsoluteCount { weight: 4 }; let voting_period = Duration::Time(2000000); let info = mock_info(OWNER, &[]); - setup_test_case(deps.as_mut(), info, required_weight, voting_period).unwrap(); + setup_test_case(deps.as_mut(), info, threshold, voting_period).unwrap(); let bank_msg = BankMsg::Send { to_address: SOMEBODY.into(), @@ -554,7 +559,7 @@ mod tests { }; let msgs = vec![CosmosMsg::Bank(bank_msg)]; - // Only voters with weight can propose + // Voter without voting power still can create proposal let info = mock_info(NOWEIGHT_VOTER, &[]); let proposal = ExecuteMsg::Propose { title: "Rewarding somebody".to_string(), @@ -562,11 +567,6 @@ mod tests { msgs, latest: None, }; - let err = execute(deps.as_mut(), mock_env(), info, proposal.clone()).unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // Propose proposal - let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), mock_env(), info, proposal).unwrap(); // Get the proposal id from the logs @@ -579,7 +579,7 @@ mod tests { }; // Only voters with weight can vote let info = mock_info(NOWEIGHT_VOTER, &[]); - execute(deps.as_mut(), mock_env(), info, no_vote).unwrap_err(); + let err = execute(deps.as_mut(), mock_env(), info, no_vote).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); } @@ -587,11 +587,11 @@ mod tests { fn test_propose_works() { let mut deps = mock_dependencies(); - let required_weight = 4; + let threshold = Threshold::AbsoluteCount { weight: 4 }; let voting_period = Duration::Time(2000000); let info = mock_info(OWNER, &[]); - setup_test_case(deps.as_mut(), info, required_weight, voting_period).unwrap(); + setup_test_case(deps.as_mut(), info, threshold, voting_period).unwrap(); let bank_msg = BankMsg::Send { to_address: SOMEBODY.into(), @@ -654,11 +654,11 @@ mod tests { fn test_vote_works() { let mut deps = mock_dependencies(); - let required_weight = 3; + let threshold = Threshold::AbsoluteCount { weight: 3 }; let voting_period = Duration::Time(2000000); let info = mock_info(OWNER, &[]); - setup_test_case(deps.as_mut(), info.clone(), required_weight, voting_period).unwrap(); + setup_test_case(deps.as_mut(), info.clone(), threshold, voting_period).unwrap(); // Propose let bank_msg = BankMsg::Send { @@ -767,11 +767,11 @@ mod tests { fn test_execute_works() { let mut deps = mock_dependencies(); - let required_weight = 3; + let threshold = Threshold::AbsoluteCount { weight: 3 }; let voting_period = Duration::Time(2000000); let info = mock_info(OWNER, &[]); - setup_test_case(deps.as_mut(), info.clone(), required_weight, voting_period).unwrap(); + setup_test_case(deps.as_mut(), info.clone(), threshold, voting_period).unwrap(); // Propose let bank_msg = BankMsg::Send { @@ -842,11 +842,11 @@ mod tests { fn test_close_works() { let mut deps = mock_dependencies(); - let required_weight = 3; + let threshold = Threshold::AbsoluteCount { weight: 3 }; let voting_period = Duration::Height(2000000); let info = mock_info(OWNER, &[]); - setup_test_case(deps.as_mut(), info.clone(), required_weight, voting_period).unwrap(); + setup_test_case(deps.as_mut(), info.clone(), threshold, voting_period).unwrap(); // Propose let bank_msg = BankMsg::Send { diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index 6da82182d..e2d7dcab5 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -1,14 +1,16 @@ #![cfg(test)] -use crate::contract::{execute, instantiate, query}; -use crate::msg::{ExecuteMsg, InstantiateMsg, Voter}; use cosmwasm_std::{to_binary, Addr, Empty, Uint128, WasmMsg}; use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; +use cw3_flex_multisig::msg::Threshold; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; use utils::Duration; +use crate::contract::{execute, instantiate, query}; +use crate::msg::{ExecuteMsg, InstantiateMsg, Voter}; + fn mock_app() -> App { App::default() } @@ -53,7 +55,7 @@ fn cw3_controls_cw20() { weight: 1, }, ], - required_weight: 2, + threshold: Threshold::AbsoluteCount { weight: 2 }, max_voting_period: Duration::Height(3), }; From 8c843cb9d53dfd6c9204b83104d323fbb2516647 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 12:45:45 +0100 Subject: [PATCH 086/631] cw3-fixed-multisig: adapt to threshold implementation being moved to utils --- contracts/cw3-fixed-multisig/src/contract.rs | 15 +++++++++------ contracts/cw3-fixed-multisig/src/error.rs | 5 +++-- .../cw3-fixed-multisig/src/integration_tests.rs | 3 +-- contracts/cw3-fixed-multisig/src/msg.rs | 3 +-- contracts/cw3-fixed-multisig/src/state.rs | 3 +-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 9097e37ad..5dd423cb7 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -405,8 +405,7 @@ mod tests { use cosmwasm_std::{coin, from_binary, BankMsg, Decimal}; use cw2::{get_contract_version, ContractVersion}; - use cw3_flex_multisig::msg::Threshold; - use utils::Duration; + use utils::{Duration, Threshold}; use crate::msg::Voter; @@ -517,15 +516,19 @@ mod tests { }; let err = instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap_err(); - - use cw3_flex_multisig::ContractError::{InvalidThreshold, UnreachableWeight}; - assert_eq!(err, ContractError::FlexMultisig(InvalidThreshold {})); + assert_eq!( + err, + ContractError::Threshold(utils::ThresholdError::InvalidThreshold {}) + ); // Total weight less than required weight not allowed let threshold = Threshold::AbsoluteCount { weight: 100 }; let err = setup_test_case(deps.as_mut(), info.clone(), threshold, max_voting_period).unwrap_err(); - assert_eq!(err, ContractError::FlexMultisig(UnreachableWeight {})); + assert_eq!( + err, + ContractError::Threshold(utils::ThresholdError::UnreachableWeight {}) + ); // All valid let threshold = Threshold::AbsoluteCount { weight: 1 }; diff --git a/contracts/cw3-fixed-multisig/src/error.rs b/contracts/cw3-fixed-multisig/src/error.rs index 83ab07362..1b4dcebf3 100644 --- a/contracts/cw3-fixed-multisig/src/error.rs +++ b/contracts/cw3-fixed-multisig/src/error.rs @@ -1,5 +1,6 @@ use cosmwasm_std::StdError; -use cw3_flex_multisig::error::ContractError as Cw3FlexMultisigError; +use utils::ThresholdError; + use thiserror::Error; #[derive(Error, Debug, PartialEq)] @@ -8,7 +9,7 @@ pub enum ContractError { Std(#[from] StdError), #[error("{0}")] - FlexMultisig(#[from] Cw3FlexMultisigError), + Threshold(#[from] ThresholdError), #[error("Required weight cannot be zero")] ZeroWeight {}, diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index e2d7dcab5..a0737a49b 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -4,9 +4,8 @@ use cosmwasm_std::{to_binary, Addr, Empty, Uint128, WasmMsg}; use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; -use cw3_flex_multisig::msg::Threshold; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; -use utils::Duration; +use utils::{Duration, Threshold}; use crate::contract::{execute, instantiate, query}; use crate::msg::{ExecuteMsg, InstantiateMsg, Voter}; diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index 81ed7801a..3ea74f2b5 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -3,8 +3,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; -use cw3_flex_multisig::msg::Threshold; -use utils::{Duration, Expiration}; +use utils::{Duration, Expiration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 27e2d2801..5b6b2cab4 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -2,9 +2,8 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::Addr; -use cw3_flex_multisig::msg::Threshold; use cw_storage_plus::{Item, Map}; -use utils::Duration; +use utils::{Duration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { From 090ccdd57c4762fcf75bdc87b12ceb56db1eedf6 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 12:55:43 +0100 Subject: [PATCH 087/631] Add note in MIGRATING.md file about breaking changes to cw3-fixed-multisig instantiate message --- MIGRATING.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/MIGRATING.md b/MIGRATING.md index 551082fca..1229109f8 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -28,6 +28,8 @@ index b4852225..f20a65ec 100644 +use utils::Expiration; ``` +--- + - Deprecate `range` to `range_raw` [\#460](https://github.com/CosmWasm/cw-plus/issues/460) / `range` to `range raw` [\#576](https://github.com/CosmWasm/cw-plus/pull/576). @@ -62,6 +64,8 @@ not only not be deserialized, but also not provided. This is for backwards-compa specifications, and may change in the future once these features are stabilized. See `packages/storage-plus/src/indexed_map.rs` tests for reference. +--- + Renamed methods: - `range` -> `range_raw` - `keys` -> `keys_raw` @@ -72,6 +76,8 @@ Renamed methods: Finally, this applies to all the `Map`-like types, including indexed maps. +--- + - `UniqueIndex` / `MultiIndex` key consistency [\#532](https://github.com/CosmWasm/cw-plus/issues/532) / Index keys consistency [\#568](https://github.com/CosmWasm/cw-plus/pull/568) @@ -134,6 +140,8 @@ index 9f7178af..d11d501e 100644 assert_eq!(data1, marias[0].1); ``` +--- + - Remove the primary key from the `MultiIndex` key specification [\#533](https://github.com/CosmWasm/cw-plus/issues/533) / `MultiIndex` primary key spec removal [\#569](https://github.com/CosmWasm/cw-plus/pull/569) @@ -183,6 +191,8 @@ index 022a4504..c7a3bb9d 100644 let count = map ``` +--- + - Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) / Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) @@ -227,6 +237,23 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result, +- pub required_weight: u64, ++ pub threshold: Threshold, + pub max_voting_period: Duration, +} +``` + ### Non-breaking Issues / PRs - Deprecate `IntKey` [\#472](https://github.com/CosmWasm/cw-plus/issues/472) / From 84228346da8c49d29186bb47d9916294d64efc0f Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 13:06:20 +0100 Subject: [PATCH 088/631] Move common proposal and vote implementation so that cw3-flex-multisig would import it from cw3-fixed-multisig --- Cargo.lock | 2 +- contracts/cw3-fixed-multisig/Cargo.toml | 1 - contracts/cw3-fixed-multisig/src/contract.rs | 4 +- contracts/cw3-fixed-multisig/src/state.rs | 359 +++++++++++++++++- contracts/cw3-flex-multisig/Cargo.toml | 1 + contracts/cw3-flex-multisig/src/contract.rs | 3 +- contracts/cw3-flex-multisig/src/state.rs | 361 +------------------ 7 files changed, 364 insertions(+), 367 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bace81e43..76114ddc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,7 +530,6 @@ dependencies = [ "cw20", "cw20-base", "cw3", - "cw3-flex-multisig", "schemars", "serde", "thiserror", @@ -547,6 +546,7 @@ dependencies = [ "cw-storage-plus", "cw2", "cw3", + "cw3-fixed-multisig", "cw4", "cw4-group", "schemars", diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 5843d0ebe..edab67af4 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -21,7 +21,6 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } -cw3-flex-multisig = { path = "../cw3-flex-multisig", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 5dd423cb7..b8ce7f05f 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -12,14 +12,12 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; -use cw3_flex_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; - use cw_storage_plus::Bound; use utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{Config, CONFIG, VOTERS}; +use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS, VOTERS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-fixed-multisig"; diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 5b6b2cab4..22a7ae50e 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -1,9 +1,15 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::Addr; +use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; + +use cw3::{Status, Vote}; use cw_storage_plus::{Item, Map}; -use utils::{Duration, Threshold}; +use utils::{Duration, Expiration, Threshold}; + +// we multiply by this when calculating needed_votes in order to round up properly +// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" +const PRECISION_FACTOR: u128 = 1_000_000_000; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { @@ -12,9 +18,358 @@ pub struct Config { pub max_voting_period: Duration, } +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Proposal { + pub title: String, + pub description: String, + pub start_height: u64, + pub expires: Expiration, + pub msgs: Vec>, + pub status: Status, + /// pass requirements + pub threshold: Threshold, + // the total weight when the proposal started (used to calculate percentages) + pub total_weight: u64, + // summary of existing votes + pub votes: Votes, +} + +impl Proposal { + /// current_status is non-mutable and returns what the status should be. + /// (designed for queries) + pub fn current_status(&self, block: &BlockInfo) -> Status { + let mut status = self.status; + + // if open, check if voting is passed or timed out + if status == Status::Open && self.is_passed(block) { + status = Status::Passed; + } + if status == Status::Open && self.expires.is_expired(block) { + status = Status::Rejected; + } + + status + } + + /// update_status sets the status of the proposal to current_status. + /// (designed for handler logic) + pub fn update_status(&mut self, block: &BlockInfo) { + self.status = self.current_status(block); + } + + // returns true iff this proposal is sure to pass (even before expiration if no future + // sequence of possible votes can cause it to fail) + pub fn is_passed(&self, block: &BlockInfo) -> bool { + match self.threshold { + Threshold::AbsoluteCount { + weight: weight_needed, + } => self.votes.yes >= weight_needed, + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => { + self.votes.yes + >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) + } + Threshold::ThresholdQuorum { threshold, quorum } => { + // we always require the quorum + if self.votes.total() < votes_needed(self.total_weight, quorum) { + return false; + } + if self.expires.is_expired(block) { + // If expired, we compare Yes votes against the total number of votes (minus abstain). + let opinions = self.votes.total() - self.votes.abstain; + self.votes.yes >= votes_needed(opinions, threshold) + } else { + // If not expired, we must assume all non-votes will be cast as No. + // We compare threshold against the total weight (minus abstain). + let possible_opinions = self.total_weight - self.votes.abstain; + self.votes.yes >= votes_needed(possible_opinions, threshold) + } + } + } + } +} + +// weight of votes for each option +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Votes { + pub yes: u64, + pub no: u64, + pub abstain: u64, + pub veto: u64, +} + +impl Votes { + /// sum of all votes + pub fn total(&self) -> u64 { + self.yes + self.no + self.abstain + self.veto + } + + /// create it with a yes vote for this much + pub fn yes(init_weight: u64) -> Self { + Votes { + yes: init_weight, + no: 0, + abstain: 0, + veto: 0, + } + } + + pub fn add_vote(&mut self, vote: Vote, weight: u64) { + match vote { + Vote::Yes => self.yes += weight, + Vote::Abstain => self.abstain += weight, + Vote::No => self.no += weight, + Vote::Veto => self.veto += weight, + } + } +} + +// this is a helper function so Decimal works with u64 rather than Uint128 +// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total +fn votes_needed(weight: u64, percentage: Decimal) -> u64 { + let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); + // Divide by PRECISION_FACTOR, rounding up to the nearest integer + ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 +} + +// we cast a ballot with our chosen vote and a given weight +// stored under the key that voted +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Ballot { + pub weight: u64, + pub vote: Vote, +} + // unique items pub const CONFIG: Item = Item::new("config"); pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); +// multiple-item map +pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("votes"); +pub const PROPOSALS: Map = Map::new("proposals"); + // multiple-item maps pub const VOTERS: Map<&Addr, u64> = Map::new("voters"); + +pub fn next_id(store: &mut dyn Storage) -> StdResult { + let id: u64 = PROPOSAL_COUNT.may_load(store)?.unwrap_or_default() + 1; + PROPOSAL_COUNT.save(store, &id)?; + Ok(id) +} + +#[cfg(test)] +mod test { + use super::*; + use cosmwasm_std::testing::mock_env; + + #[test] + fn count_votes() { + let mut votes = Votes::yes(5); + votes.add_vote(Vote::No, 10); + votes.add_vote(Vote::Veto, 20); + votes.add_vote(Vote::Yes, 30); + votes.add_vote(Vote::Abstain, 40); + + assert_eq!(votes.total(), 105); + assert_eq!(votes.yes, 35); + assert_eq!(votes.no, 10); + assert_eq!(votes.veto, 20); + assert_eq!(votes.abstain, 40); + } + + #[test] + // we ensure this rounds up (as it calculates needed votes) + fn votes_needed_rounds_properly() { + // round up right below 1 + assert_eq!(1, votes_needed(3, Decimal::permille(333))); + // round up right over 1 + assert_eq!(2, votes_needed(3, Decimal::permille(334))); + assert_eq!(11, votes_needed(30, Decimal::permille(334))); + + // exact matches don't round + assert_eq!(17, votes_needed(34, Decimal::percent(50))); + assert_eq!(12, votes_needed(48, Decimal::percent(25))); + } + + fn check_is_passed( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> bool { + let block = mock_env().block; + let expires = match is_expired { + true => Expiration::AtHeight(block.height - 5), + false => Expiration::AtHeight(block.height + 100), + }; + let prop = Proposal { + title: "Demo".to_string(), + description: "Info".to_string(), + start_height: 100, + expires, + msgs: vec![], + status: Status::Open, + threshold, + total_weight, + votes, + }; + prop.is_passed(&block) + } + + #[test] + fn proposal_passed_absolute_count() { + let fixed = Threshold::AbsoluteCount { weight: 10 }; + let mut votes = Votes::yes(7); + votes.add_vote(Vote::Veto, 4); + // same expired or not, total_weight or whatever + assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, false)); + assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, true)); + // a few more yes votes and we are good + votes.add_vote(Vote::Yes, 3); + assert!(check_is_passed(fixed.clone(), votes.clone(), 30, false)); + assert!(check_is_passed(fixed, votes, 30, true)); + } + + #[test] + fn proposal_passed_absolute_percentage() { + let percent = Threshold::AbsolutePercentage { + percentage: Decimal::percent(50), + }; + let mut votes = Votes::yes(7); + votes.add_vote(Vote::No, 4); + votes.add_vote(Vote::Abstain, 2); + // same expired or not, if yes >= ceiling(0.5 * (total - abstained)) + // 7 of (15-2) passes + assert!(check_is_passed(percent.clone(), votes.clone(), 15, false)); + assert!(check_is_passed(percent.clone(), votes.clone(), 15, true)); + // but 7 of (17-2) fails + assert!(!check_is_passed(percent.clone(), votes.clone(), 17, false)); + + // if the total were a bit lower, this would pass + assert!(check_is_passed(percent.clone(), votes.clone(), 14, false)); + assert!(check_is_passed(percent, votes, 14, true)); + } + + #[test] + fn proposal_passed_quorum() { + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(50), + quorum: Decimal::percent(40), + }; + // all non-yes votes are counted for quorum + let passing = Votes { + yes: 7, + no: 3, + abstain: 2, + veto: 1, + }; + // abstain votes are not counted for threshold => yes / (yes + no + veto) + let passes_ignoring_abstain = Votes { + yes: 6, + no: 4, + abstain: 5, + veto: 2, + }; + // fails any way you look at it + let failing = Votes { + yes: 6, + no: 5, + abstain: 2, + veto: 2, + }; + + // first, expired (voting period over) + // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) + assert!(check_is_passed(quorum.clone(), passing.clone(), 30, true)); + // under quorum it is not passing (40% of 33 = 13.2 > 13) + assert!(!check_is_passed(quorum.clone(), passing.clone(), 33, true)); + // over quorum, threshold passes if we ignore abstain + // 17 total votes w/ abstain => 40% quorum of 40 total + // 6 yes / (6 yes + 4 no + 2 votes) => 50% threshold + assert!(check_is_passed( + quorum.clone(), + passes_ignoring_abstain.clone(), + 40, + true + )); + // over quorum, but under threshold fails also + assert!(!check_is_passed(quorum.clone(), failing, 20, true)); + + // now, check with open voting period + // would pass if closed, but fail here, as remaining votes no -> fail + assert!(!check_is_passed(quorum.clone(), passing.clone(), 30, false)); + assert!(!check_is_passed( + quorum.clone(), + passes_ignoring_abstain.clone(), + 40, + false + )); + // if we have threshold * total_weight as yes votes this must pass + assert!(check_is_passed(quorum.clone(), passing.clone(), 14, false)); + // all votes have been cast, some abstain + assert!(check_is_passed( + quorum.clone(), + passes_ignoring_abstain, + 17, + false + )); + // 3 votes uncast, if they all vote no, we have 7 yes, 7 no+veto, 2 abstain (out of 16) + assert!(check_is_passed(quorum, passing, 16, false)); + } + + #[test] + fn quorum_edge_cases() { + // when we pass absolute threshold (everyone else voting no, we pass), but still don't hit quorum + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(60), + quorum: Decimal::percent(80), + }; + + // try 9 yes, 1 no (out of 15) -> 90% voter threshold, 60% absolute threshold, still no quorum + // doesn't matter if expired or not + let missing_voters = Votes { + yes: 9, + no: 1, + abstain: 0, + veto: 0, + }; + assert!(!check_is_passed( + quorum.clone(), + missing_voters.clone(), + 15, + false + )); + assert!(!check_is_passed(quorum.clone(), missing_voters, 15, true)); + + // 1 less yes, 3 vetos and this passes only when expired + let wait_til_expired = Votes { + yes: 8, + no: 1, + abstain: 0, + veto: 3, + }; + assert!(!check_is_passed( + quorum.clone(), + wait_til_expired.clone(), + 15, + false + )); + assert!(check_is_passed(quorum.clone(), wait_til_expired, 15, true)); + + // 9 yes and 3 nos passes early + let passes_early = Votes { + yes: 9, + no: 3, + abstain: 0, + veto: 0, + }; + assert!(check_is_passed( + quorum.clone(), + passes_early.clone(), + 15, + false + )); + assert!(check_is_passed(quorum, passes_early, 15, true)); + } +} diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index d4d8e8608..07e8e689d 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -21,6 +21,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3" } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index d870652c5..dd8168c40 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -12,13 +12,14 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; +use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS}; +use crate::state::{Config, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 59b1518b4..987c57237 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,16 +1,9 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; - -use cw3::{Status, Vote}; use cw4::Cw4Contract; -use cw_storage_plus::{Item, Map}; -use utils::{Duration, Expiration, Threshold}; - -// we multiply by this when calculating needed_votes in order to round up properly -// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" -const PRECISION_FACTOR: u128 = 1_000_000_000; +use cw_storage_plus::Item; +use utils::{Duration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { @@ -20,355 +13,5 @@ pub struct Config { pub group_addr: Cw4Contract, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Proposal { - pub title: String, - pub description: String, - pub start_height: u64, - pub expires: Expiration, - pub msgs: Vec>, - pub status: Status, - /// pass requirements - pub threshold: Threshold, - // the total weight when the proposal started (used to calculate percentages) - pub total_weight: u64, - // summary of existing votes - pub votes: Votes, -} - -// weight of votes for each option -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Votes { - pub yes: u64, - pub no: u64, - pub abstain: u64, - pub veto: u64, -} - -impl Votes { - /// sum of all votes - pub fn total(&self) -> u64 { - self.yes + self.no + self.abstain + self.veto - } - - /// create it with a yes vote for this much - pub fn yes(init_weight: u64) -> Self { - Votes { - yes: init_weight, - no: 0, - abstain: 0, - veto: 0, - } - } - - pub fn add_vote(&mut self, vote: Vote, weight: u64) { - match vote { - Vote::Yes => self.yes += weight, - Vote::Abstain => self.abstain += weight, - Vote::No => self.no += weight, - Vote::Veto => self.veto += weight, - } - } -} - -impl Proposal { - /// current_status is non-mutable and returns what the status should be. - /// (designed for queries) - pub fn current_status(&self, block: &BlockInfo) -> Status { - let mut status = self.status; - - // if open, check if voting is passed or timed out - if status == Status::Open && self.is_passed(block) { - status = Status::Passed; - } - if status == Status::Open && self.expires.is_expired(block) { - status = Status::Rejected; - } - - status - } - - /// update_status sets the status of the proposal to current_status. - /// (designed for handler logic) - pub fn update_status(&mut self, block: &BlockInfo) { - self.status = self.current_status(block); - } - - // returns true iff this proposal is sure to pass (even before expiration if no future - // sequence of possible votes can cause it to fail) - pub fn is_passed(&self, block: &BlockInfo) -> bool { - match self.threshold { - Threshold::AbsoluteCount { - weight: weight_needed, - } => self.votes.yes >= weight_needed, - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => { - self.votes.yes - >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) - } - Threshold::ThresholdQuorum { threshold, quorum } => { - // we always require the quorum - if self.votes.total() < votes_needed(self.total_weight, quorum) { - return false; - } - if self.expires.is_expired(block) { - // If expired, we compare Yes votes against the total number of votes (minus abstain). - let opinions = self.votes.total() - self.votes.abstain; - self.votes.yes >= votes_needed(opinions, threshold) - } else { - // If not expired, we must assume all non-votes will be cast as No. - // We compare threshold against the total weight (minus abstain). - let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.yes >= votes_needed(possible_opinions, threshold) - } - } - } - } -} - -// this is a helper function so Decimal works with u64 rather than Uint128 -// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total -fn votes_needed(weight: u64, percentage: Decimal) -> u64 { - let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); - // Divide by PRECISION_FACTOR, rounding up to the nearest integer - ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 -} - -// we cast a ballot with our chosen vote and a given weight -// stored under the key that voted -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Ballot { - pub weight: u64, - pub vote: Vote, -} - // unique items pub const CONFIG: Item = Item::new("config"); -pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); - -// multiple-item map -pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("votes"); -pub const PROPOSALS: Map = Map::new("proposals"); - -pub fn next_id(store: &mut dyn Storage) -> StdResult { - let id: u64 = PROPOSAL_COUNT.may_load(store)?.unwrap_or_default() + 1; - PROPOSAL_COUNT.save(store, &id)?; - Ok(id) -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::mock_env; - - #[test] - fn count_votes() { - let mut votes = Votes::yes(5); - votes.add_vote(Vote::No, 10); - votes.add_vote(Vote::Veto, 20); - votes.add_vote(Vote::Yes, 30); - votes.add_vote(Vote::Abstain, 40); - - assert_eq!(votes.total(), 105); - assert_eq!(votes.yes, 35); - assert_eq!(votes.no, 10); - assert_eq!(votes.veto, 20); - assert_eq!(votes.abstain, 40); - } - - #[test] - // we ensure this rounds up (as it calculates needed votes) - fn votes_needed_rounds_properly() { - // round up right below 1 - assert_eq!(1, votes_needed(3, Decimal::permille(333))); - // round up right over 1 - assert_eq!(2, votes_needed(3, Decimal::permille(334))); - assert_eq!(11, votes_needed(30, Decimal::permille(334))); - - // exact matches don't round - assert_eq!(17, votes_needed(34, Decimal::percent(50))); - assert_eq!(12, votes_needed(48, Decimal::percent(25))); - } - - fn check_is_passed( - threshold: Threshold, - votes: Votes, - total_weight: u64, - is_expired: bool, - ) -> bool { - let block = mock_env().block; - let expires = match is_expired { - true => Expiration::AtHeight(block.height - 5), - false => Expiration::AtHeight(block.height + 100), - }; - let prop = Proposal { - title: "Demo".to_string(), - description: "Info".to_string(), - start_height: 100, - expires, - msgs: vec![], - status: Status::Open, - threshold, - total_weight, - votes, - }; - prop.is_passed(&block) - } - - #[test] - fn proposal_passed_absolute_count() { - let fixed = Threshold::AbsoluteCount { weight: 10 }; - let mut votes = Votes::yes(7); - votes.add_vote(Vote::Veto, 4); - // same expired or not, total_weight or whatever - assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, false)); - assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, true)); - // a few more yes votes and we are good - votes.add_vote(Vote::Yes, 3); - assert!(check_is_passed(fixed.clone(), votes.clone(), 30, false)); - assert!(check_is_passed(fixed, votes, 30, true)); - } - - #[test] - fn proposal_passed_absolute_percentage() { - let percent = Threshold::AbsolutePercentage { - percentage: Decimal::percent(50), - }; - let mut votes = Votes::yes(7); - votes.add_vote(Vote::No, 4); - votes.add_vote(Vote::Abstain, 2); - // same expired or not, if yes >= ceiling(0.5 * (total - abstained)) - // 7 of (15-2) passes - assert!(check_is_passed(percent.clone(), votes.clone(), 15, false)); - assert!(check_is_passed(percent.clone(), votes.clone(), 15, true)); - // but 7 of (17-2) fails - assert!(!check_is_passed(percent.clone(), votes.clone(), 17, false)); - - // if the total were a bit lower, this would pass - assert!(check_is_passed(percent.clone(), votes.clone(), 14, false)); - assert!(check_is_passed(percent, votes, 14, true)); - } - - #[test] - fn proposal_passed_quorum() { - let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(50), - quorum: Decimal::percent(40), - }; - // all non-yes votes are counted for quorum - let passing = Votes { - yes: 7, - no: 3, - abstain: 2, - veto: 1, - }; - // abstain votes are not counted for threshold => yes / (yes + no + veto) - let passes_ignoring_abstain = Votes { - yes: 6, - no: 4, - abstain: 5, - veto: 2, - }; - // fails any way you look at it - let failing = Votes { - yes: 6, - no: 5, - abstain: 2, - veto: 2, - }; - - // first, expired (voting period over) - // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) - assert!(check_is_passed(quorum.clone(), passing.clone(), 30, true)); - // under quorum it is not passing (40% of 33 = 13.2 > 13) - assert!(!check_is_passed(quorum.clone(), passing.clone(), 33, true)); - // over quorum, threshold passes if we ignore abstain - // 17 total votes w/ abstain => 40% quorum of 40 total - // 6 yes / (6 yes + 4 no + 2 votes) => 50% threshold - assert!(check_is_passed( - quorum.clone(), - passes_ignoring_abstain.clone(), - 40, - true - )); - // over quorum, but under threshold fails also - assert!(!check_is_passed(quorum.clone(), failing, 20, true)); - - // now, check with open voting period - // would pass if closed, but fail here, as remaining votes no -> fail - assert!(!check_is_passed(quorum.clone(), passing.clone(), 30, false)); - assert!(!check_is_passed( - quorum.clone(), - passes_ignoring_abstain.clone(), - 40, - false - )); - // if we have threshold * total_weight as yes votes this must pass - assert!(check_is_passed(quorum.clone(), passing.clone(), 14, false)); - // all votes have been cast, some abstain - assert!(check_is_passed( - quorum.clone(), - passes_ignoring_abstain, - 17, - false - )); - // 3 votes uncast, if they all vote no, we have 7 yes, 7 no+veto, 2 abstain (out of 16) - assert!(check_is_passed(quorum, passing, 16, false)); - } - - #[test] - fn quorum_edge_cases() { - // when we pass absolute threshold (everyone else voting no, we pass), but still don't hit quorum - let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(60), - quorum: Decimal::percent(80), - }; - - // try 9 yes, 1 no (out of 15) -> 90% voter threshold, 60% absolute threshold, still no quorum - // doesn't matter if expired or not - let missing_voters = Votes { - yes: 9, - no: 1, - abstain: 0, - veto: 0, - }; - assert!(!check_is_passed( - quorum.clone(), - missing_voters.clone(), - 15, - false - )); - assert!(!check_is_passed(quorum.clone(), missing_voters, 15, true)); - - // 1 less yes, 3 vetos and this passes only when expired - let wait_til_expired = Votes { - yes: 8, - no: 1, - abstain: 0, - veto: 3, - }; - assert!(!check_is_passed( - quorum.clone(), - wait_til_expired.clone(), - 15, - false - )); - assert!(check_is_passed(quorum.clone(), wait_til_expired, 15, true)); - - // 9 yes and 3 nos passes early - let passes_early = Votes { - yes: 9, - no: 3, - abstain: 0, - veto: 0, - }; - assert!(check_is_passed( - quorum.clone(), - passes_early.clone(), - 15, - false - )); - assert!(check_is_passed(quorum, passes_early, 15, true)); - } -} From bf72c5496f93b0078eb7e0a608ffd705a613af74 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 13:49:06 +0100 Subject: [PATCH 089/631] cw3-flex-multisig: Bring back common Ballot, Proposal etc. implementations --- Cargo.lock | 1 - contracts/cw3-flex-multisig/Cargo.toml | 1 - contracts/cw3-flex-multisig/src/contract.rs | 3 +- contracts/cw3-flex-multisig/src/state.rs | 145 +++++++++++++++++++- 4 files changed, 144 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76114ddc1..43fed7b8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -546,7 +546,6 @@ dependencies = [ "cw-storage-plus", "cw2", "cw3", - "cw3-fixed-multisig", "cw4", "cw4-group", "schemars", diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 07e8e689d..d4d8e8608 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -21,7 +21,6 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3" } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index dd8168c40..d870652c5 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -12,14 +12,13 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; -use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{Config, CONFIG}; +use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 987c57237..67ce09658 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,9 +1,16 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; + +use cw3::{Status, Vote}; use cw4::Cw4Contract; -use cw_storage_plus::Item; -use utils::{Duration, Threshold}; +use cw_storage_plus::{Item, Map}; +use utils::{Duration, Expiration, Threshold}; + +// we multiply by this when calculating needed_votes in order to round up properly +// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" +const PRECISION_FACTOR: u128 = 1_000_000_000; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { @@ -13,5 +20,139 @@ pub struct Config { pub group_addr: Cw4Contract, } +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Proposal { + pub title: String, + pub description: String, + pub start_height: u64, + pub expires: Expiration, + pub msgs: Vec>, + pub status: Status, + /// pass requirements + pub threshold: Threshold, + // the total weight when the proposal started (used to calculate percentages) + pub total_weight: u64, + // summary of existing votes + pub votes: Votes, +} + +// weight of votes for each option +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Votes { + pub yes: u64, + pub no: u64, + pub abstain: u64, + pub veto: u64, +} + +impl Votes { + /// sum of all votes + pub fn total(&self) -> u64 { + self.yes + self.no + self.abstain + self.veto + } + + /// create it with a yes vote for this much + pub fn yes(init_weight: u64) -> Self { + Votes { + yes: init_weight, + no: 0, + abstain: 0, + veto: 0, + } + } + + pub fn add_vote(&mut self, vote: Vote, weight: u64) { + match vote { + Vote::Yes => self.yes += weight, + Vote::Abstain => self.abstain += weight, + Vote::No => self.no += weight, + Vote::Veto => self.veto += weight, + } + } +} + +impl Proposal { + /// current_status is non-mutable and returns what the status should be. + /// (designed for queries) + pub fn current_status(&self, block: &BlockInfo) -> Status { + let mut status = self.status; + + // if open, check if voting is passed or timed out + if status == Status::Open && self.is_passed(block) { + status = Status::Passed; + } + if status == Status::Open && self.expires.is_expired(block) { + status = Status::Rejected; + } + + status + } + + /// update_status sets the status of the proposal to current_status. + /// (designed for handler logic) + pub fn update_status(&mut self, block: &BlockInfo) { + self.status = self.current_status(block); + } + + // returns true iff this proposal is sure to pass (even before expiration if no future + // sequence of possible votes can cause it to fail) + pub fn is_passed(&self, block: &BlockInfo) -> bool { + match self.threshold { + Threshold::AbsoluteCount { + weight: weight_needed, + } => self.votes.yes >= weight_needed, + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => { + self.votes.yes + >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) + } + Threshold::ThresholdQuorum { threshold, quorum } => { + // we always require the quorum + if self.votes.total() < votes_needed(self.total_weight, quorum) { + return false; + } + if self.expires.is_expired(block) { + // If expired, we compare Yes votes against the total number of votes (minus abstain). + let opinions = self.votes.total() - self.votes.abstain; + self.votes.yes >= votes_needed(opinions, threshold) + } else { + // If not expired, we must assume all non-votes will be cast as No. + // We compare threshold against the total weight (minus abstain). + let possible_opinions = self.total_weight - self.votes.abstain; + self.votes.yes >= votes_needed(possible_opinions, threshold) + } + } + } + } +} + +// this is a helper function so Decimal works with u64 rather than Uint128 +// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total +fn votes_needed(weight: u64, percentage: Decimal) -> u64 { + let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); + // Divide by PRECISION_FACTOR, rounding up to the nearest integer + ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 +} + +// we cast a ballot with our chosen vote and a given weight +// stored under the key that voted +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct Ballot { + pub weight: u64, + pub vote: Vote, +} + // unique items pub const CONFIG: Item = Item::new("config"); +pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); + +// multiple-item map +pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("votes"); +pub const PROPOSALS: Map = Map::new("proposals"); + +pub fn next_id(store: &mut dyn Storage) -> StdResult { + let id: u64 = PROPOSAL_COUNT.may_load(store)?.unwrap_or_default() + 1; + PROPOSAL_COUNT.save(store, &id)?; + Ok(id) +} From b5ead3dd5c07a274e1d0211bc8314fb57777de09 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 15:18:18 +0100 Subject: [PATCH 090/631] Revert "cw3-flex-multisig: Bring back common Ballot, Proposal etc. implementations" This reverts commit bf72c5496f93b0078eb7e0a608ffd705a613af74. --- Cargo.lock | 1 + contracts/cw3-flex-multisig/Cargo.toml | 1 + contracts/cw3-flex-multisig/src/contract.rs | 3 +- contracts/cw3-flex-multisig/src/state.rs | 145 +------------------- 4 files changed, 6 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43fed7b8b..76114ddc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -546,6 +546,7 @@ dependencies = [ "cw-storage-plus", "cw2", "cw3", + "cw3-fixed-multisig", "cw4", "cw4-group", "schemars", diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index d4d8e8608..07e8e689d 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -21,6 +21,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3" } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index d870652c5..dd8168c40 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -12,13 +12,14 @@ use cw3::{ ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; +use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS}; +use crate::state::{Config, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 67ce09658..987c57237 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,16 +1,9 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; - -use cw3::{Status, Vote}; use cw4::Cw4Contract; -use cw_storage_plus::{Item, Map}; -use utils::{Duration, Expiration, Threshold}; - -// we multiply by this when calculating needed_votes in order to round up properly -// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" -const PRECISION_FACTOR: u128 = 1_000_000_000; +use cw_storage_plus::Item; +use utils::{Duration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { @@ -20,139 +13,5 @@ pub struct Config { pub group_addr: Cw4Contract, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Proposal { - pub title: String, - pub description: String, - pub start_height: u64, - pub expires: Expiration, - pub msgs: Vec>, - pub status: Status, - /// pass requirements - pub threshold: Threshold, - // the total weight when the proposal started (used to calculate percentages) - pub total_weight: u64, - // summary of existing votes - pub votes: Votes, -} - -// weight of votes for each option -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Votes { - pub yes: u64, - pub no: u64, - pub abstain: u64, - pub veto: u64, -} - -impl Votes { - /// sum of all votes - pub fn total(&self) -> u64 { - self.yes + self.no + self.abstain + self.veto - } - - /// create it with a yes vote for this much - pub fn yes(init_weight: u64) -> Self { - Votes { - yes: init_weight, - no: 0, - abstain: 0, - veto: 0, - } - } - - pub fn add_vote(&mut self, vote: Vote, weight: u64) { - match vote { - Vote::Yes => self.yes += weight, - Vote::Abstain => self.abstain += weight, - Vote::No => self.no += weight, - Vote::Veto => self.veto += weight, - } - } -} - -impl Proposal { - /// current_status is non-mutable and returns what the status should be. - /// (designed for queries) - pub fn current_status(&self, block: &BlockInfo) -> Status { - let mut status = self.status; - - // if open, check if voting is passed or timed out - if status == Status::Open && self.is_passed(block) { - status = Status::Passed; - } - if status == Status::Open && self.expires.is_expired(block) { - status = Status::Rejected; - } - - status - } - - /// update_status sets the status of the proposal to current_status. - /// (designed for handler logic) - pub fn update_status(&mut self, block: &BlockInfo) { - self.status = self.current_status(block); - } - - // returns true iff this proposal is sure to pass (even before expiration if no future - // sequence of possible votes can cause it to fail) - pub fn is_passed(&self, block: &BlockInfo) -> bool { - match self.threshold { - Threshold::AbsoluteCount { - weight: weight_needed, - } => self.votes.yes >= weight_needed, - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => { - self.votes.yes - >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) - } - Threshold::ThresholdQuorum { threshold, quorum } => { - // we always require the quorum - if self.votes.total() < votes_needed(self.total_weight, quorum) { - return false; - } - if self.expires.is_expired(block) { - // If expired, we compare Yes votes against the total number of votes (minus abstain). - let opinions = self.votes.total() - self.votes.abstain; - self.votes.yes >= votes_needed(opinions, threshold) - } else { - // If not expired, we must assume all non-votes will be cast as No. - // We compare threshold against the total weight (minus abstain). - let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.yes >= votes_needed(possible_opinions, threshold) - } - } - } - } -} - -// this is a helper function so Decimal works with u64 rather than Uint128 -// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total -fn votes_needed(weight: u64, percentage: Decimal) -> u64 { - let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); - // Divide by PRECISION_FACTOR, rounding up to the nearest integer - ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 -} - -// we cast a ballot with our chosen vote and a given weight -// stored under the key that voted -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Ballot { - pub weight: u64, - pub vote: Vote, -} - // unique items pub const CONFIG: Item = Item::new("config"); -pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); - -// multiple-item map -pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("votes"); -pub const PROPOSALS: Map = Map::new("proposals"); - -pub fn next_id(store: &mut dyn Storage) -> StdResult { - let id: u64 = PROPOSAL_COUNT.may_load(store)?.unwrap_or_default() + 1; - PROPOSAL_COUNT.save(store, &id)?; - Ok(id) -} From 0c72eb1e455b96d5c8eff30bd0e17c3d022123cf Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 15:18:51 +0100 Subject: [PATCH 091/631] Use feature library to avoid duplicated symbols --- contracts/cw3-flex-multisig/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 07e8e689d..cc9f70b8d 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -21,7 +21,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.10.3" } cw2 = { path = "../../packages/cw2", version = "0.10.3" } cw3 = { path = "../../packages/cw3", version = "0.10.3" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.10.3" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } cosmwasm-std = { version = "1.0.0-beta3" } From 718e5c73241b8529791aa6ef22453760a45aa0e9 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 13:59:32 +0100 Subject: [PATCH 092/631] Set version: 0.11.0 --- Cargo.lock | 48 ++++++++++++------------ contracts/cw1-subkeys/Cargo.toml | 14 +++---- contracts/cw1-whitelist-ng/Cargo.toml | 14 +++---- contracts/cw1-whitelist/Cargo.toml | 12 +++--- contracts/cw1155-base/Cargo.toml | 10 ++--- contracts/cw20-atomic-swap/Cargo.toml | 10 ++--- contracts/cw20-base/Cargo.toml | 10 ++--- contracts/cw20-bonding/Cargo.toml | 12 +++--- contracts/cw20-escrow/Cargo.toml | 14 +++---- contracts/cw20-ics20/Cargo.toml | 10 ++--- contracts/cw20-merkle-airdrop/Cargo.toml | 8 ++-- contracts/cw20-staking/Cargo.toml | 14 +++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 ++++---- contracts/cw3-flex-multisig/Cargo.toml | 17 ++++----- contracts/cw4-group/Cargo.toml | 12 +++--- contracts/cw4-stake/Cargo.toml | 14 +++---- packages/controllers/Cargo.toml | 6 +-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +- packages/cw2/Cargo.toml | 4 +- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 4 +- packages/multi-test/Cargo.toml | 6 +-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +- 26 files changed, 137 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76114ddc1..4e2824967 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,7 +241,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -253,7 +253,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.10.3" +version = "0.11.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -270,7 +270,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-std", "schemars", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -289,7 +289,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.10.3" +version = "0.11.0" dependencies = [ "anyhow", "assert_matches", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.10.3" +version = "0.11.0" dependencies = [ "anyhow", "assert_matches", @@ -344,7 +344,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -355,7 +355,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -370,7 +370,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -380,7 +380,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -391,7 +391,7 @@ dependencies = [ [[package]] name = "cw20-atomic-swap" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -423,7 +423,7 @@ dependencies = [ [[package]] name = "cw20-bonding" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -442,7 +442,7 @@ dependencies = [ [[package]] name = "cw20-escrow" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -459,7 +459,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -492,7 +492,7 @@ dependencies = [ [[package]] name = "cw20-staking" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -509,7 +509,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -520,7 +520,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -557,7 +557,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -568,7 +568,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -584,7 +584,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1170,7 +1170,7 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "utils" -version = "0.10.3" +version = "0.11.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index acdc2d8db..3bfa738ef 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw1 = { path = "../../packages/cw1", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library"] } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw1 = { path = "../../packages/cw1", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.0", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.10.3", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index e439b6264..31d3ed5aa 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.10.3" +version = "0.11.0" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw1 = { path = "../../packages/cw1", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw1 = { path = "../../packages/cw1", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 22d7a9218..9ae2ddf08 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw1 = { path = "../../packages/cw1", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw1 = { path = "../../packages/cw1", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 0e9859c4d..35cd30461 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.10.3" +version = "0.11.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw1155 = { path = "../../packages/cw1155", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-atomic-swap/Cargo.toml b/contracts/cw20-atomic-swap/Cargo.toml index 7da558616..fd724cec8 100644 --- a/contracts/cw20-atomic-swap/Cargo.toml +++ b/contracts/cw20-atomic-swap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-atomic-swap" -version = "0.10.3" +version = "0.11.0" authors = ["Mauro Lacy "] edition = "2018" description = "Implementation of Atomic Swaps" @@ -15,11 +15,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index dbd87339a..40961b4ff 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-bonding/Cargo.toml b/contracts/cw20-bonding/Cargo.toml index 4479a7f67..e48160be3 100644 --- a/contracts/cw20-bonding/Cargo.toml +++ b/contracts/cw20-bonding/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-bonding" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement basic bonding curve to issue cw20 tokens" @@ -20,11 +20,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.10.3", features = ["library"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw20-base = { path = "../../contracts/cw20-base", version = "0.11.0", features = ["library"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", default-features = false, features = ["staking"] } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-escrow/Cargo.toml b/contracts/cw20-escrow/Cargo.toml index 9727002a8..2914a0b0f 100644 --- a/contracts/cw20-escrow/Cargo.toml +++ b/contracts/cw20-escrow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-escrow" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an escrow that accepts CosmWasm-20 tokens as well as native tokens" @@ -18,16 +18,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } -cw20-base = { path = "../cw20-base", version = "0.10.3", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } +cw20-base = { path = "../cw20-base", version = "0.11.0", features = ["library"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 53443d2a7..6cc4050a8 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,11 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-merkle-airdrop/Cargo.toml b/contracts/cw20-merkle-airdrop/Cargo.toml index f9ef8cc9c..8db60cd38 100644 --- a/contracts/cw20-merkle-airdrop/Cargo.toml +++ b/contracts/cw20-merkle-airdrop/Cargo.toml @@ -19,11 +19,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-staking/Cargo.toml b/contracts/cw20-staking/Cargo.toml index e3effd870..42c10175b 100644 --- a/contracts/cw20-staking/Cargo.toml +++ b/contracts/cw20-staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-staking" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement simple staking derivatives as a cw20 token" @@ -20,13 +20,13 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.10.3", features = ["library"] } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } +cw20-base = { path = "../../contracts/cw20-base", version = "0.11.0", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index edab67af4..c2a5cf04e 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw3 = { path = "../../packages/cw3", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw3 = { path = "../../packages/cw3", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cw20-base = { path = "../cw20-base", version = "0.10.3", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw20-base = { path = "../cw20-base", version = "0.11.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index cc9f70b8d..be01f7a0f 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw3 = { path = "../../packages/cw3", version = "0.10.3" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.10.3", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw3 = { path = "../../packages/cw3", version = "0.11.0" } +cw4 = { path = "../../packages/cw4", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +30,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw4-group = { path = "../cw4-group", version = "0.10.3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.10.3" } +cw4-group = { path = "../cw4-group", version = "0.11.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index a4dc89f4b..cf599b1f6 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw4 = { path = "../../packages/cw4", version = "0.10.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw4 = { path = "../../packages/cw4", version = "0.11.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index c07504e07..041677d03 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw2 = { path = "../../packages/cw2", version = "0.10.3" } -cw4 = { path = "../../packages/cw4", version = "0.10.3" } -cw20 = { path = "../../packages/cw20", version = "0.10.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } +cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw4 = { path = "../../packages/cw4", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 5d99266c3..783163a6e 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3" } -utils = { path = "../utils", version = "0.10.3" } -cw-storage-plus = { path = "../storage-plus", version = "0.10.3" } +utils = { path = "../utils", version = "0.11.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 75b2bcdbf..01cdea229 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 808ab5625..9048f5217 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.10.3" +version = "0.11.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index fc492461b..3d3e6bb71 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index fd47608e4..1ba7559ff 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 1e483eac8..1031b591a 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } +utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index cd531b9da..bd428f71a 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index e2f7c0dfe..bf6c909ae 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -utils = { path = "../../packages/utils", version = "0.10.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3"} +utils = { path = "../../packages/utils", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0"} cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta3" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 9635d6a49..30f622807 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index f0a2ecd3d..c85f70302 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "utils" -version = "0.10.3" +version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.10.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } prost = "0.9" From b1c393a95e92270ad99525da0572a0de08533344 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 15:46:06 +0100 Subject: [PATCH 093/631] Update CHANGELOG.md --- CHANGELOG.md | 63 +++++++++++++++++++++++++- contracts/cw3-flex-multisig/Cargo.toml | 1 + 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74efa90ad..74f04f2e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,68 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.10.3...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.0...HEAD) + +## [v0.11.0](https://github.com/CosmWasm/cw-plus/tree/v0.11.0) (2021-11-22) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.10.3...v0.11.0) + +**Breaking changes:** + +- Remove the primary key from the `MultiIndex` key specification [\#533](https://github.com/CosmWasm/cw-plus/issues/533) +- `UniqueIndex` / `MultiIndex` key consistency [\#532](https://github.com/CosmWasm/cw-plus/issues/532) +- Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) +- Deprecate `range` to `range_raw` [\#460](https://github.com/CosmWasm/cw-plus/issues/460) + +**Implemented enhancements:** + +- Add `MIGRATING.md` [\#583](https://github.com/CosmWasm/cw-plus/issues/583) +- Remove schemas, and publish them with artifacts on release tags [\#529](https://github.com/CosmWasm/cw-plus/issues/529) + +**Closed issues:** + +- Check \(and possibly fix\) threshold and voting power implementation in `cw3-fixed-multisig` [\#551](https://github.com/CosmWasm/cw-plus/issues/551) +- Update to cosmwasm 1.0.0-beta3 [\#579](https://github.com/CosmWasm/cw-plus/issues/579) +- Cannot import non "library" features in dev-dependencies [\#577](https://github.com/CosmWasm/cw-plus/issues/577) +- `base-helpers.ts` doesn't belong to `contracts` [\#566](https://github.com/CosmWasm/cw-plus/issues/566) +- handle function [\#563](https://github.com/CosmWasm/cw-plus/issues/563) +- Migrate from `IntKey` to new naked int key [\#549](https://github.com/CosmWasm/cw-plus/issues/549) +- Refactor `UniqueIndex` and `MultiIndex` into their own files [\#530](https://github.com/CosmWasm/cw-plus/issues/530) +- Iterate over historical data in SnapshotMap [\#487](https://github.com/CosmWasm/cw-plus/issues/487) +- Rename cw0 to utils [\#471](https://github.com/CosmWasm/cw-plus/issues/471) +- Various `range_de` / `prefix_de` improvements [\#464](https://github.com/CosmWasm/cw-plus/issues/464) +- Add `range_de` to `Map`-like structs [\#461](https://github.com/CosmWasm/cw-plus/issues/461) +- Add url as input when mint cw1155 [\#449](https://github.com/CosmWasm/cw-plus/issues/449) +- Allow cw20 token as reserve token for bonding curve [\#191](https://github.com/CosmWasm/cw-plus/issues/191) +- Benchmark bonding curve functionality [\#190](https://github.com/CosmWasm/cw-plus/issues/190) +- Support Partial Indexes [\#177](https://github.com/CosmWasm/cw-plus/issues/177) +- Improve cw20-staking contract [\#59](https://github.com/CosmWasm/cw-plus/issues/59) + +**Merged pull requests:** + +- Add `MIGRATING.md` [\#591](https://github.com/CosmWasm/cw-plus/pull/591) ([maurolacy](https://github.com/maurolacy)) +- Move Threshold and coexisting implementations into packages/utils [\#590](https://github.com/CosmWasm/cw-plus/pull/590) ([ueco-jb](https://github.com/ueco-jb)) +- Build and upload schemas in CI [\#589](https://github.com/CosmWasm/cw-plus/pull/589) ([maurolacy](https://github.com/maurolacy)) +- Fix min threshold and vote power bugs in cw3-fixed-multisig [\#588](https://github.com/CosmWasm/cw-plus/pull/588) ([ueco-jb](https://github.com/ueco-jb)) +- Update to cosmwasm 1.0.0-beta3 [\#587](https://github.com/CosmWasm/cw-plus/pull/587) ([ueco-jb](https://github.com/ueco-jb)) +- Make `update_changelog.sh` use the latest version tag by default [\#585](https://github.com/CosmWasm/cw-plus/pull/585) ([maurolacy](https://github.com/maurolacy)) +- Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) ([maurolacy](https://github.com/maurolacy)) +- `range` to `range raw` [\#576](https://github.com/CosmWasm/cw-plus/pull/576) ([maurolacy](https://github.com/maurolacy)) +- Remove helper.ts files for contracts [\#574](https://github.com/CosmWasm/cw-plus/pull/574) ([findolor](https://github.com/findolor)) +- Fix expiration type properties on cw1-subkeys helpers.ts [\#571](https://github.com/CosmWasm/cw-plus/pull/571) ([findolor](https://github.com/findolor)) +- `MultiIndex` primary key spec removal [\#569](https://github.com/CosmWasm/cw-plus/pull/569) ([maurolacy](https://github.com/maurolacy)) +- Index keys consistency [\#568](https://github.com/CosmWasm/cw-plus/pull/568) ([maurolacy](https://github.com/maurolacy)) +- Implement display for Balance and Coin [\#565](https://github.com/CosmWasm/cw-plus/pull/565) ([orkunkl](https://github.com/orkunkl)) +- Migrate from `IntKey` to new naked int key [\#564](https://github.com/CosmWasm/cw-plus/pull/564) ([ueco-jb](https://github.com/ueco-jb)) +- Add ParseReplyError to cw0 lib [\#562](https://github.com/CosmWasm/cw-plus/pull/562) ([shanev](https://github.com/shanev)) +- Update cw2 readme - contract\_info key [\#561](https://github.com/CosmWasm/cw-plus/pull/561) ([korzewski](https://github.com/korzewski)) +- Change pebblenet to uni and update wasm binary to 0.10.2 [\#560](https://github.com/CosmWasm/cw-plus/pull/560) ([findolor](https://github.com/findolor)) +- Update cw1-subkeys/helpers.ts wasm binary version to 0.10.2 from 0.9.1 [\#558](https://github.com/CosmWasm/cw-plus/pull/558) ([findolor](https://github.com/findolor)) +- Update base-helpers.ts options [\#557](https://github.com/CosmWasm/cw-plus/pull/557) ([findolor](https://github.com/findolor)) +- Update cw4-group/helpers.ts to work with base-helpers.ts [\#552](https://github.com/CosmWasm/cw-plus/pull/552) ([findolor](https://github.com/findolor)) +- Update cw3-flex-multisig/helpers.ts to work with cosmjs/cli v0.26 and base-helpers.ts [\#550](https://github.com/CosmWasm/cw-plus/pull/550) ([findolor](https://github.com/findolor)) +- Cw0 rename [\#508](https://github.com/CosmWasm/cw-plus/pull/508) ([maurolacy](https://github.com/maurolacy)) +- UniqueIndex range\_de [\#500](https://github.com/CosmWasm/cw-plus/pull/500) ([uint](https://github.com/uint)) ## [v0.10.3](https://github.com/CosmWasm/cw-plus/tree/v0.10.3) (2021-11-16) diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index be01f7a0f..448f6e947 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -21,6 +21,7 @@ library = [] utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw3 = { path = "../../packages/cw3", version = "0.11.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.11.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.11.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } From bd88a92d9c653586bf94381e121ff775c8f7f89a Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Wed, 22 Dec 2021 16:26:50 +0100 Subject: [PATCH 094/631] Mantion latest workspace optimizer version in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f9098648..6e088d295 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.3 + cosmwasm/workspace-optimizer:0.12.4 ``` This will compile all packages in the `contracts` directory and output the From 4c5b8bfb8ac4069e3aad3085b85fb19dc2e259c7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 16:41:23 +0100 Subject: [PATCH 095/631] Fix artifacts publishing so that schemas are not deleted --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 126a9c128..718b56953 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -848,7 +848,7 @@ jobs: -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ -c "$CIRCLE_SHA1" \ -n "$TITLE" -b "$BODY" \ - -delete \ + -replace \ "$TAG" ./artifacts/ build_and_upload_schemas: From a478ec2d7e595a38670927bdd05447cda79dc64e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 22 Dec 2021 16:43:06 +0100 Subject: [PATCH 096/631] Update workspace-optimizer to latest version in CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 718b56953..7bdf9d52e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -831,7 +831,7 @@ jobs: - run: name: Build development contracts command: | - docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.3 + docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.4 docker cp with_code:/code/artifacts ./artifacts - run: name: Show data From b4e8e671f96e0020ae92a262abf679db4bd8e27a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 22 Dec 2021 21:47:34 +0100 Subject: [PATCH 097/631] add context to multitest execution errors --- packages/multi-test/src/contracts.rs | 26 +++++++++++++++++++------- packages/multi-test/src/executor.rs | 25 ++++++++++++++++++------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 8b0af4079..bf88b1158 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -6,7 +6,7 @@ use cosmwasm_std::{ from_slice, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Reply, Response, SubMsg, }; -use anyhow::{anyhow, bail, Result as AnyResult}; +use anyhow::{anyhow, bail, Context, Result as AnyResult}; /// Interface to call into a Contract pub trait Contract @@ -65,7 +65,7 @@ pub struct ContractWrapper< T6 = Empty, E6 = anyhow::Error, > where - T1: DeserializeOwned, + T1: DeserializeOwned + Debug, T2: DeserializeOwned, T3: DeserializeOwned, T4: DeserializeOwned, @@ -88,7 +88,7 @@ pub struct ContractWrapper< impl ContractWrapper where - T1: DeserializeOwned + 'static, + T1: DeserializeOwned + Debug + 'static, T2: DeserializeOwned + 'static, T3: DeserializeOwned + 'static, E1: Display + Debug + Send + Sync + 'static, @@ -132,7 +132,7 @@ where impl ContractWrapper where - T1: DeserializeOwned + 'static, + T1: DeserializeOwned + Debug + 'static, T2: DeserializeOwned + 'static, T3: DeserializeOwned + 'static, T4: DeserializeOwned + 'static, @@ -317,7 +317,7 @@ where impl Contract for ContractWrapper where - T1: DeserializeOwned, + T1: DeserializeOwned + Debug + Clone, T2: DeserializeOwned, T3: DeserializeOwned, T4: DeserializeOwned, @@ -337,8 +337,20 @@ where info: MessageInfo, msg: Vec, ) -> AnyResult> { - let msg = from_slice(&msg)?; - (self.execute_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) + let msg: T1 = from_slice(&msg)?; + let address = env.contract.address.clone(); + (self.execute_fn)(deps, env, info.clone(), msg.clone()) + .map_err(|err| anyhow!("{}", err)) + .context(format!( + r#"Contract returned an error on execute +Contract address: {} +Message sender: {} +Funds: {:?} +Message dump: +{:?} +"#, + address, info.sender, info.funds, msg, + )) } fn instantiate( diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index 6e1e8678d..31fe75ee5 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -8,7 +8,7 @@ use schemars::JsonSchema; use serde::Serialize; use utils::{parse_execute_response_data, parse_instantiate_response_data}; -use anyhow::Result as AnyResult; +use anyhow::{Context, Result as AnyResult}; #[derive(Default, Clone, Debug)] pub struct AppResponse { @@ -98,20 +98,31 @@ where /// Execute a contract and process all returned messages. /// This is just a helper around execute(), /// but we parse out the data field to that what is returned by the contract (not the protobuf wrapper) - fn execute_contract( + fn execute_contract( &mut self, sender: Addr, contract_addr: Addr, msg: &T, send_funds: &[Coin], ) -> AnyResult { - let msg = to_binary(msg)?; - let msg = WasmMsg::Execute { - contract_addr: contract_addr.into(), - msg, + let binary_msg = to_binary(msg)?; + let wrapped_msg = WasmMsg::Execute { + contract_addr: contract_addr.to_string(), + msg: binary_msg, funds: send_funds.to_vec(), }; - let mut res = self.execute(sender, msg.into())?; + let mut res = self + .execute(sender.clone(), wrapped_msg.into()) + .context(format!( + r#"Contract returned an error on execute +Contract address: {} +Message sender: {} +Funds: {:?} +Message dump: +{:?} +"#, + contract_addr, sender, send_funds, msg, + ))?; res.data = res .data .and_then(|d| parse_execute_response_data(d.as_slice()).unwrap().data); From a4aa4b691c10e57bdcfc9a680c7cf4d7740f8ea9 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 22 Dec 2021 23:00:21 +0100 Subject: [PATCH 098/631] Rename utils to cw-utils --- Cargo.lock | 64 +++++++++---------- MIGRATING.md | 6 +- contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-subkeys/src/contract.rs | 4 +- contracts/cw1-subkeys/src/error.rs | 2 +- contracts/cw1-subkeys/src/msg.rs | 4 +- contracts/cw1-subkeys/src/state.rs | 4 +- contracts/cw1-whitelist-ng/Cargo.toml | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- contracts/cw1155-base/Cargo.toml | 2 +- contracts/cw1155-base/src/contract.rs | 2 +- contracts/cw20-atomic-swap/Cargo.toml | 2 +- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-bonding/Cargo.toml | 2 +- contracts/cw20-bonding/src/contract.rs | 4 +- contracts/cw20-bonding/src/error.rs | 2 +- contracts/cw20-escrow/Cargo.toml | 2 +- contracts/cw20-ics20/Cargo.toml | 2 +- contracts/cw20-ics20/src/contract.rs | 4 +- contracts/cw20-ics20/src/error.rs | 2 +- contracts/cw20-merkle-airdrop/Cargo.toml | 2 +- contracts/cw20-staking/Cargo.toml | 2 +- contracts/cw20-staking/src/contract.rs | 2 +- contracts/cw20-staking/src/msg.rs | 2 +- contracts/cw20-staking/src/state.rs | 2 +- contracts/cw3-fixed-multisig/Cargo.toml | 2 +- contracts/cw3-fixed-multisig/src/contract.rs | 8 +-- contracts/cw3-fixed-multisig/src/error.rs | 2 +- .../src/integration_tests.rs | 2 +- contracts/cw3-fixed-multisig/src/msg.rs | 2 +- contracts/cw3-fixed-multisig/src/state.rs | 2 +- contracts/cw3-flex-multisig/Cargo.toml | 2 +- contracts/cw3-flex-multisig/src/contract.rs | 8 +-- contracts/cw3-flex-multisig/src/error.rs | 2 +- contracts/cw3-flex-multisig/src/msg.rs | 2 +- contracts/cw3-flex-multisig/src/state.rs | 2 +- contracts/cw4-group/Cargo.toml | 2 +- contracts/cw4-group/src/contract.rs | 2 +- contracts/cw4-stake/Cargo.toml | 2 +- contracts/cw4-stake/src/contract.rs | 4 +- contracts/cw4-stake/src/msg.rs | 2 +- contracts/cw4-stake/src/state.rs | 2 +- packages/controllers/Cargo.toml | 2 +- packages/controllers/src/claim.rs | 2 +- packages/cw1155/Cargo.toml | 2 +- packages/cw1155/src/event.rs | 2 +- packages/cw1155/src/lib.rs | 2 +- packages/cw1155/src/msg.rs | 2 +- packages/cw1155/src/query.rs | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw20/src/balance.rs | 2 +- packages/cw20/src/lib.rs | 2 +- packages/cw20/src/msg.rs | 2 +- packages/cw20/src/query.rs | 2 +- packages/cw3/Cargo.toml | 2 +- packages/cw3/examples/schema.rs | 2 +- packages/cw3/src/helpers.rs | 2 +- packages/cw3/src/msg.rs | 2 +- packages/cw3/src/query.rs | 2 +- packages/multi-test/Cargo.toml | 2 +- packages/multi-test/src/app.rs | 2 +- packages/multi-test/src/bank.rs | 2 +- packages/multi-test/src/executor.rs | 2 +- .../src/test_helpers/contracts/echo.rs | 2 +- packages/utils/Cargo.toml | 2 +- 65 files changed, 110 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e2824967..74175f326 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,10 +245,10 @@ version = "0.11.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", + "cw-utils", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -259,13 +259,13 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus", + "cw-utils", "derivative", "itertools", "prost", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -277,6 +277,18 @@ dependencies = [ "serde", ] +[[package]] +name = "cw-utils" +version = "0.11.0" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "prost", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw1" version = "0.11.0" @@ -294,6 +306,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw1", "cw1-whitelist", "cw2", @@ -301,7 +314,6 @@ dependencies = [ "semver", "serde", "thiserror", - "utils", ] [[package]] @@ -314,13 +326,13 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus", + "cw-utils", "cw1", "cw2", "derivative", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -333,13 +345,13 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus", + "cw-utils", "cw1", "cw2", "derivative", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -348,9 +360,9 @@ version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-utils", "schemars", "serde", - "utils", ] [[package]] @@ -360,12 +372,12 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw1155", "cw2", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -384,9 +396,9 @@ version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-utils", "schemars", "serde", - "utils", ] [[package]] @@ -396,6 +408,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "hex 0.3.2", @@ -403,7 +416,6 @@ dependencies = [ "serde", "sha2 0.8.2", "thiserror", - "utils", ] [[package]] @@ -413,12 +425,12 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -428,6 +440,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "cw20-base", @@ -437,7 +450,6 @@ dependencies = [ "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -448,13 +460,13 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "cw20-base", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -464,12 +476,12 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -479,6 +491,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "hex 0.4.3", @@ -487,7 +500,6 @@ dependencies = [ "serde_json", "sha2 0.9.8", "thiserror", - "utils", ] [[package]] @@ -498,13 +510,13 @@ dependencies = [ "cosmwasm-std", "cw-controllers", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "cw20-base", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -513,9 +525,9 @@ version = "0.11.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-utils", "schemars", "serde", - "utils", ] [[package]] @@ -526,6 +538,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "cw20-base", @@ -533,7 +546,6 @@ dependencies = [ "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -544,6 +556,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus", + "cw-utils", "cw2", "cw3", "cw3-fixed-multisig", @@ -552,7 +565,6 @@ dependencies = [ "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -574,12 +586,12 @@ dependencies = [ "cosmwasm-std", "cw-controllers", "cw-storage-plus", + "cw-utils", "cw2", "cw4", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -590,13 +602,13 @@ dependencies = [ "cosmwasm-std", "cw-controllers", "cw-storage-plus", + "cw-utils", "cw2", "cw20", "cw4", "schemars", "serde", "thiserror", - "utils", ] [[package]] @@ -1168,18 +1180,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "utils" -version = "0.11.0" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "prost", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "version_check" version = "0.9.3" diff --git a/MIGRATING.md b/MIGRATING.md index 1229109f8..c8da916c3 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -16,7 +16,7 @@ index 1924b655..37af477d 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml -cw0 = { path = "../../packages/cw0", version = "0.10.3" } -+utils = { path = "../../packages/utils", version = "0.10.3" } ++cw-utils = { path = "../../packages/utils", version = "0.10.3" } ``` ```diff @@ -25,7 +25,7 @@ index b4852225..f20a65ec 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs -use cw0::Expiration; -+use utils::Expiration; ++use cw_utils::Expiration; ``` --- @@ -244,7 +244,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result, diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 3bfa738ef..5c487ff9c 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,7 +19,7 @@ library = [] test-utils = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw1 = { path = "../../packages/cw1", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.0", features = ["library"] } diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index fca7ee1a4..1d0f2bbb9 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -19,8 +19,8 @@ use cw1_whitelist::{ }; use cw2::{get_contract_version, set_contract_version}; use cw_storage_plus::Bound; +use cw_utils::Expiration; use semver::Version; -use utils::Expiration; use crate::error::ContractError; use crate::msg::{ @@ -477,7 +477,7 @@ mod tests { use cw1_whitelist::msg::AdminListResponse; use cw2::{get_contract_version, ContractVersion}; - use utils::NativeBalance; + use cw_utils::NativeBalance; use crate::state::Permissions; diff --git a/contracts/cw1-subkeys/src/error.rs b/contracts/cw1-subkeys/src/error.rs index f79605f28..acafc9376 100644 --- a/contracts/cw1-subkeys/src/error.rs +++ b/contracts/cw1-subkeys/src/error.rs @@ -1,6 +1,6 @@ use cosmwasm_std::StdError; +use cw_utils::Expiration; use thiserror::Error; -use utils::Expiration; #[derive(Error, Debug, PartialEq)] pub enum ContractError { diff --git a/contracts/cw1-subkeys/src/msg.rs b/contracts/cw1-subkeys/src/msg.rs index a7ddf89dd..3af6943ef 100644 --- a/contracts/cw1-subkeys/src/msg.rs +++ b/contracts/cw1-subkeys/src/msg.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use cosmwasm_std::{Coin, CosmosMsg, Empty}; -use utils::{Expiration, NativeBalance}; +use cw_utils::{Expiration, NativeBalance}; use crate::state::Permissions; @@ -112,7 +112,7 @@ impl AllowanceInfo { /// Example: /// /// ``` - /// # use utils::{Expiration, NativeBalance}; + /// # use cw_utils::{Expiration, NativeBalance}; /// # use cw1_subkeys::msg::AllowanceInfo; /// # use cosmwasm_std::coin; /// diff --git a/contracts/cw1-subkeys/src/state.rs b/contracts/cw1-subkeys/src/state.rs index 007354c17..866e419eb 100644 --- a/contracts/cw1-subkeys/src/state.rs +++ b/contracts/cw1-subkeys/src/state.rs @@ -4,7 +4,7 @@ use std::fmt; use cosmwasm_std::Addr; use cw_storage_plus::Map; -use utils::{Expiration, NativeBalance}; +use cw_utils::{Expiration, NativeBalance}; // Permissions struct defines users message execution permissions. // Could have implemented permissions for each cosmos module(StakingPermissions, GovPermissions etc...) @@ -46,7 +46,7 @@ impl Allowance { /// Example: /// /// ``` - /// # use utils::{Expiration, NativeBalance}; + /// # use cw_utils::{Expiration, NativeBalance}; /// # use cw1_subkeys::state::Allowance; /// # use cosmwasm_std::coin; /// diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 31d3ed5aa..d03d5d474 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -22,7 +22,7 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw1 = { path = "../../packages/cw1", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 9ae2ddf08..4ca281d08 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,7 +19,7 @@ library = [] test-utils = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw1 = { path = "../../packages/cw1", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 35cd30461..16ccfc160 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw1155 = { path = "../../packages/cw1155", version = "0.11.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index e3195cff3..611d3e41c 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -11,7 +11,7 @@ use cw1155::{ IsApprovedForAllResponse, TokenId, TokenInfoResponse, TokensResponse, TransferEvent, }; use cw2::set_contract_version; -use utils::{maybe_addr, Event}; +use cw_utils::{maybe_addr, Event}; use crate::error::ContractError; use crate::msg::InstantiateMsg; diff --git a/contracts/cw20-atomic-swap/Cargo.toml b/contracts/cw20-atomic-swap/Cargo.toml index fd724cec8..3f9fc0797 100644 --- a/contracts/cw20-atomic-swap/Cargo.toml +++ b/contracts/cw20-atomic-swap/Cargo.toml @@ -15,7 +15,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 40961b4ff..ae494f080 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } diff --git a/contracts/cw20-bonding/Cargo.toml b/contracts/cw20-bonding/Cargo.toml index e48160be3..fea0d5065 100644 --- a/contracts/cw20-bonding/Cargo.toml +++ b/contracts/cw20-bonding/Cargo.toml @@ -20,7 +20,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cw20-base = { path = "../../contracts/cw20-base", version = "0.11.0", features = ["library"] } diff --git a/contracts/cw20-bonding/src/contract.rs b/contracts/cw20-bonding/src/contract.rs index 01a5b8b62..a3a33aed2 100644 --- a/contracts/cw20-bonding/src/contract.rs +++ b/contracts/cw20-bonding/src/contract.rs @@ -19,7 +19,7 @@ use crate::curves::DecimalPlaces; use crate::error::ContractError; use crate::msg::{CurveFn, CurveInfoResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{CurveState, CURVE_STATE, CURVE_TYPE}; -use utils::{must_pay, nonpayable}; +use cw_utils::{must_pay, nonpayable}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw20-bonding"; @@ -314,7 +314,7 @@ mod tests { use crate::msg::CurveType; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{coin, Decimal, OverflowError, OverflowOperation, StdError, SubMsg}; - use utils::PaymentError; + use cw_utils::PaymentError; const DENOM: &str = "satoshi"; const CREATOR: &str = "creator"; diff --git a/contracts/cw20-bonding/src/error.rs b/contracts/cw20-bonding/src/error.rs index dd2d577bf..aa6bcc9ab 100644 --- a/contracts/cw20-bonding/src/error.rs +++ b/contracts/cw20-bonding/src/error.rs @@ -1,6 +1,6 @@ use cosmwasm_std::StdError; +use cw_utils::PaymentError; use thiserror::Error; -use utils::PaymentError; #[derive(Error, Debug, PartialEq)] pub enum ContractError { diff --git a/contracts/cw20-escrow/Cargo.toml b/contracts/cw20-escrow/Cargo.toml index 2914a0b0f..a41fbc36a 100644 --- a/contracts/cw20-escrow/Cargo.toml +++ b/contracts/cw20-escrow/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 6cc4050a8..b268ea558 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 132c08dd6..fc4ffb7e6 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -16,7 +16,7 @@ use crate::msg::{ TransferMsg, }; use crate::state::{Config, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; -use utils::{nonpayable, one_coin}; +use cw_utils::{nonpayable, one_coin}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw20-ics20"; @@ -191,7 +191,7 @@ mod test { use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::{coin, coins, CosmosMsg, IbcMsg, StdError, Uint128}; - use utils::PaymentError; + use cw_utils::PaymentError; #[test] fn setup_and_query() { diff --git a/contracts/cw20-ics20/src/error.rs b/contracts/cw20-ics20/src/error.rs index 64082ef3c..c20a0b4d5 100644 --- a/contracts/cw20-ics20/src/error.rs +++ b/contracts/cw20-ics20/src/error.rs @@ -3,7 +3,7 @@ use std::string::FromUtf8Error; use thiserror::Error; use cosmwasm_std::StdError; -use utils::PaymentError; +use cw_utils::PaymentError; /// Never is a placeholder to ensure we don't return any errors #[derive(Error, Debug)] diff --git a/contracts/cw20-merkle-airdrop/Cargo.toml b/contracts/cw20-merkle-airdrop/Cargo.toml index 8db60cd38..ba108b805 100644 --- a/contracts/cw20-merkle-airdrop/Cargo.toml +++ b/contracts/cw20-merkle-airdrop/Cargo.toml @@ -19,7 +19,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-staking/Cargo.toml b/contracts/cw20-staking/Cargo.toml index 42c10175b..75d2c7123 100644 --- a/contracts/cw20-staking/Cargo.toml +++ b/contracts/cw20-staking/Cargo.toml @@ -20,7 +20,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } diff --git a/contracts/cw20-staking/src/contract.rs b/contracts/cw20-staking/src/contract.rs index 672162155..a64dc0174 100644 --- a/contracts/cw20-staking/src/contract.rs +++ b/contracts/cw20-staking/src/contract.rs @@ -439,7 +439,7 @@ mod tests { Validator, }; use cw_controllers::Claim; - use utils::{Duration, DAY, HOUR, WEEK}; + use cw_utils::{Duration, DAY, HOUR, WEEK}; fn sample_validator(addr: &str) -> Validator { Validator { diff --git a/contracts/cw20-staking/src/msg.rs b/contracts/cw20-staking/src/msg.rs index facf326ed..b9c22f11b 100644 --- a/contracts/cw20-staking/src/msg.rs +++ b/contracts/cw20-staking/src/msg.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{Binary, Coin, Decimal, Uint128}; use cw20::Expiration; pub use cw_controllers::ClaimsResponse; -use utils::Duration; +use cw_utils::Duration; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct InstantiateMsg { diff --git a/contracts/cw20-staking/src/state.rs b/contracts/cw20-staking/src/state.rs index 3e23fdca3..e179665fd 100644 --- a/contracts/cw20-staking/src/state.rs +++ b/contracts/cw20-staking/src/state.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{Addr, Decimal, Uint128}; use cw_controllers::Claims; use cw_storage_plus::Item; -use utils::Duration; +use cw_utils::Duration; pub const CLAIMS: Claims = Claims::new("claims"); diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index c2a5cf04e..445e8d66a 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw3 = { path = "../../packages/cw3", version = "0.11.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index b8ce7f05f..394e9bc69 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -13,7 +13,7 @@ use cw3::{ VoterDetail, VoterListResponse, VoterResponse, }; use cw_storage_plus::Bound; -use utils::{Expiration, ThresholdResponse}; +use cw_utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -403,7 +403,7 @@ mod tests { use cosmwasm_std::{coin, from_binary, BankMsg, Decimal}; use cw2::{get_contract_version, ContractVersion}; - use utils::{Duration, Threshold}; + use cw_utils::{Duration, Threshold}; use crate::msg::Voter; @@ -516,7 +516,7 @@ mod tests { instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap_err(); assert_eq!( err, - ContractError::Threshold(utils::ThresholdError::InvalidThreshold {}) + ContractError::Threshold(cw_utils::ThresholdError::InvalidThreshold {}) ); // Total weight less than required weight not allowed @@ -525,7 +525,7 @@ mod tests { setup_test_case(deps.as_mut(), info.clone(), threshold, max_voting_period).unwrap_err(); assert_eq!( err, - ContractError::Threshold(utils::ThresholdError::UnreachableWeight {}) + ContractError::Threshold(cw_utils::ThresholdError::UnreachableWeight {}) ); // All valid diff --git a/contracts/cw3-fixed-multisig/src/error.rs b/contracts/cw3-fixed-multisig/src/error.rs index 1b4dcebf3..ff0b523d6 100644 --- a/contracts/cw3-fixed-multisig/src/error.rs +++ b/contracts/cw3-fixed-multisig/src/error.rs @@ -1,5 +1,5 @@ use cosmwasm_std::StdError; -use utils::ThresholdError; +use cw_utils::ThresholdError; use thiserror::Error; diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index a0737a49b..d9caf9e41 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -5,7 +5,7 @@ use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; -use utils::{Duration, Threshold}; +use cw_utils::{Duration, Threshold}; use crate::contract::{execute, instantiate, query}; use crate::msg::{ExecuteMsg, InstantiateMsg, Voter}; diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index 3ea74f2b5..18ed4eedd 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; -use utils::{Duration, Expiration, Threshold}; +use cw_utils::{Duration, Expiration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 22a7ae50e..92dbbe62f 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storag use cw3::{Status, Vote}; use cw_storage_plus::{Item, Map}; -use utils::{Duration, Expiration, Threshold}; +use cw_utils::{Duration, Expiration, Threshold}; // we multiply by this when calculating needed_votes in order to round up properly // Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 448f6e947..47b517f22 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -18,7 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw3 = { path = "../../packages/cw3", version = "0.11.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.11.0", features = ["library"] } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index dd8168c40..929975136 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -15,7 +15,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 utils::{maybe_addr, Expiration, ThresholdResponse}; +use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -432,7 +432,7 @@ mod tests { use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; use cw_multi_test::{next_block, App, AppBuilder, Contract, ContractWrapper, Executor}; - use utils::{Duration, Threshold}; + use cw_utils::{Duration, Threshold}; use super::*; @@ -626,7 +626,7 @@ mod tests { ) .unwrap_err(); assert_eq!( - ContractError::Threshold(utils::ThresholdError::InvalidThreshold {}), + ContractError::Threshold(cw_utils::ThresholdError::InvalidThreshold {}), err.downcast().unwrap() ); @@ -647,7 +647,7 @@ mod tests { ) .unwrap_err(); assert_eq!( - ContractError::Threshold(utils::ThresholdError::UnreachableWeight {}), + ContractError::Threshold(cw_utils::ThresholdError::UnreachableWeight {}), err.downcast().unwrap() ); diff --git a/contracts/cw3-flex-multisig/src/error.rs b/contracts/cw3-flex-multisig/src/error.rs index 4a56312bb..4936a8923 100644 --- a/contracts/cw3-flex-multisig/src/error.rs +++ b/contracts/cw3-flex-multisig/src/error.rs @@ -1,5 +1,5 @@ use cosmwasm_std::StdError; -use utils::ThresholdError; +use cw_utils::ThresholdError; use thiserror::Error; diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 9b6fa67ef..8d72cd37b 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; use cw4::MemberChangedHookMsg; -use utils::{Duration, Expiration, Threshold}; +use cw_utils::{Duration, Expiration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 987c57237..023662b8b 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use cw4::Cw4Contract; use cw_storage_plus::Item; -use utils::{Duration, Threshold}; +use cw_utils::{Duration, Threshold}; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index cf599b1f6..1918a243e 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -26,7 +26,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw4 = { path = "../../packages/cw4", version = "0.11.0" } cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index e41e9d9f6..cc3ec20c2 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -10,7 +10,7 @@ use cw4::{ TotalWeightResponse, }; use cw_storage_plus::Bound; -use utils::maybe_addr; +use cw_utils::maybe_addr; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 041677d03..1709658ee 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -26,7 +26,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw2 = { path = "../../packages/cw2", version = "0.11.0" } cw4 = { path = "../../packages/cw4", version = "0.11.0" } cw20 = { path = "../../packages/cw20", version = "0.11.0" } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 635a20080..e1d372083 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -12,7 +12,7 @@ use cw4::{ TotalWeightResponse, }; use cw_storage_plus::Bound; -use utils::{maybe_addr, NativeBalance}; +use cw_utils::{maybe_addr, NativeBalance}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg, StakedResponse}; @@ -364,7 +364,7 @@ mod tests { use cw20::Denom; use cw4::{member_key, TOTAL_KEY}; use cw_controllers::{AdminError, Claim, HookError}; - use utils::Duration; + use cw_utils::Duration; use crate::error::ContractError; diff --git a/contracts/cw4-stake/src/msg.rs b/contracts/cw4-stake/src/msg.rs index 6c5d76bb4..29e81f595 100644 --- a/contracts/cw4-stake/src/msg.rs +++ b/contracts/cw4-stake/src/msg.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cw20::{Cw20ReceiveMsg, Denom}; pub use cw_controllers::ClaimsResponse; -use utils::Duration; +use cw_utils::Duration; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { diff --git a/contracts/cw4-stake/src/state.rs b/contracts/cw4-stake/src/state.rs index 0a60a4a18..d8c69f98b 100644 --- a/contracts/cw4-stake/src/state.rs +++ b/contracts/cw4-stake/src/state.rs @@ -6,7 +6,7 @@ use cw20::Denom; use cw4::TOTAL_KEY; use cw_controllers::{Admin, Claims, Hooks}; use cw_storage_plus::{Item, Map, SnapshotMap, Strategy}; -use utils::Duration; +use cw_utils::Duration; pub const CLAIMS: Claims = Claims::new("claims"); diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 783163a6e..df6e54b45 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3" } -utils = { path = "../utils", version = "0.11.0" } +cw-utils = { path = "../utils", version = "0.11.0" } cw-storage-plus = { path = "../storage-plus", version = "0.11.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index b4d1b502c..a6d6c3d25 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{Addr, BlockInfo, Deps, StdResult, Storage, Uint128}; use cw_storage_plus::Map; -use utils::Expiration; +use cw_utils::Expiration; // TODO: pull into utils? #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 9048f5217..632249d32 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw1155/src/event.rs b/packages/cw1155/src/event.rs index cfe58f378..2d7709fa8 100644 --- a/packages/cw1155/src/event.rs +++ b/packages/cw1155/src/event.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{attr, Response, Uint128}; -use utils::Event; +use cw_utils::Event; /// Tracks token transfer/mint/burn actions pub struct TransferEvent<'a> { diff --git a/packages/cw1155/src/lib.rs b/packages/cw1155/src/lib.rs index 13c67588d..dfea27c4f 100644 --- a/packages/cw1155/src/lib.rs +++ b/packages/cw1155/src/lib.rs @@ -1,4 +1,4 @@ -pub use utils::Expiration; +pub use cw_utils::Expiration; pub use crate::event::{ApproveAllEvent, MetadataEvent, TransferEvent}; pub use crate::msg::{Cw1155ExecuteMsg, TokenId}; diff --git a/packages/cw1155/src/msg.rs b/packages/cw1155/src/msg.rs index d22612b3c..ab087dd40 100644 --- a/packages/cw1155/src/msg.rs +++ b/packages/cw1155/src/msg.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{Binary, Uint128}; -use utils::Expiration; +use cw_utils::Expiration; pub type TokenId = String; diff --git a/packages/cw1155/src/query.rs b/packages/cw1155/src/query.rs index 911e207b5..059d18899 100644 --- a/packages/cw1155/src/query.rs +++ b/packages/cw1155/src/query.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::Uint128; -use utils::Expiration; +use cw_utils::Expiration; use crate::msg::TokenId; diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 1ba7559ff..95df78df0 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/src/balance.rs b/packages/cw20/src/balance.rs index 17af539e9..e59c0b343 100644 --- a/packages/cw20/src/balance.rs +++ b/packages/cw20/src/balance.rs @@ -3,7 +3,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt; -use utils::NativeBalance; +use cw_utils::NativeBalance; use crate::Cw20CoinVerified; diff --git a/packages/cw20/src/lib.rs b/packages/cw20/src/lib.rs index 125fc682c..f5a142b27 100644 --- a/packages/cw20/src/lib.rs +++ b/packages/cw20/src/lib.rs @@ -1,4 +1,4 @@ -pub use utils::Expiration; +pub use cw_utils::Expiration; pub use crate::balance::Balance; pub use crate::coin::{Cw20Coin, Cw20CoinVerified}; diff --git a/packages/cw20/src/msg.rs b/packages/cw20/src/msg.rs index 16df9e5b6..4a7518b54 100644 --- a/packages/cw20/src/msg.rs +++ b/packages/cw20/src/msg.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::logo::Logo; use cosmwasm_std::{Binary, Uint128}; -use utils::Expiration; +use cw_utils::Expiration; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] #[serde(rename_all = "snake_case")] diff --git a/packages/cw20/src/query.rs b/packages/cw20/src/query.rs index c697ef61f..747db132a 100644 --- a/packages/cw20/src/query.rs +++ b/packages/cw20/src/query.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{Addr, Binary, Uint128}; use crate::logo::LogoInfo; -use utils::Expiration; +use cw_utils::Expiration; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] #[serde(rename_all = "snake_case")] diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 1031b591a..eddc95d4f 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/examples/schema.rs b/packages/cw3/examples/schema.rs index 53329e81e..39981fa0b 100644 --- a/packages/cw3/examples/schema.rs +++ b/packages/cw3/examples/schema.rs @@ -7,7 +7,7 @@ use cw3::{ Cw3ExecuteMsg, Cw3QueryMsg, ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, }; -use utils::ThresholdResponse; +use cw_utils::ThresholdResponse; fn main() { let mut out_dir = current_dir().unwrap(); diff --git a/packages/cw3/src/helpers.rs b/packages/cw3/src/helpers.rs index ba095f3c5..3bc56d10b 100644 --- a/packages/cw3/src/helpers.rs +++ b/packages/cw3/src/helpers.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::{Cw3ExecuteMsg, Vote}; -use utils::Expiration; +use cw_utils::Expiration; /// Cw3Contract is a wrapper around Addr that provides a lot of helpers /// for working with this. diff --git a/packages/cw3/src/msg.rs b/packages/cw3/src/msg.rs index 1abe72740..0811690fb 100644 --- a/packages/cw3/src/msg.rs +++ b/packages/cw3/src/msg.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use cosmwasm_std::{CosmosMsg, Empty}; -use utils::Expiration; +use cw_utils::Expiration; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] #[serde(rename_all = "snake_case")] diff --git a/packages/cw3/src/query.rs b/packages/cw3/src/query.rs index ea28e918e..bde729e6c 100644 --- a/packages/cw3/src/query.rs +++ b/packages/cw3/src/query.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use cosmwasm_std::{CosmosMsg, Empty}; -use utils::{Expiration, ThresholdResponse}; +use cw_utils::{Expiration, ThresholdResponse}; use crate::msg::Vote; diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index bf6c909ae..f29bd906e 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -18,7 +18,7 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0"} cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta3" } diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 7af9792e2..b9e22c1a8 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2441,7 +2441,7 @@ mod test { mod protobuf_wrapped_data { use super::*; use crate::test_helpers::contracts::echo::EXECUTE_REPLY_BASE_ID; - use utils::parse_instantiate_response_data; + use cw_utils::parse_instantiate_response_data; #[test] fn instantiate_wrapped_properly() { diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs index f8585ac9c..33b540784 100644 --- a/packages/multi-test/src/bank.rs +++ b/packages/multi-test/src/bank.rs @@ -8,7 +8,7 @@ use cosmwasm_std::{ }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::Map; -use utils::NativeBalance; +use cw_utils::NativeBalance; use crate::app::CosmosRouter; use crate::executor::AppResponse; diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index 6e1e8678d..4d23082a0 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -4,9 +4,9 @@ use cosmwasm_std::{ to_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, Event, SubMsgExecutionResponse, WasmMsg, }; +use cw_utils::{parse_execute_response_data, parse_instantiate_response_data}; use schemars::JsonSchema; use serde::Serialize; -use utils::{parse_execute_response_data, parse_instantiate_response_data}; use anyhow::Result as AnyResult; diff --git a/packages/multi-test/src/test_helpers/contracts/echo.rs b/packages/multi-test/src/test_helpers/contracts/echo.rs index cfbd41465..71737d530 100644 --- a/packages/multi-test/src/test_helpers/contracts/echo.rs +++ b/packages/multi-test/src/test_helpers/contracts/echo.rs @@ -13,8 +13,8 @@ use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; use schemars::JsonSchema; use std::fmt::Debug; +use cw_utils::{parse_execute_response_data, parse_instantiate_response_data}; use derivative::Derivative; -use utils::{parse_execute_response_data, parse_instantiate_response_data}; // Choosing a reply id less than ECHO_EXECUTE_BASE_ID indicates an Instantiate message reply by convention. // An Execute message reply otherwise. diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index c85f70302..7c920b592 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "utils" +name = "cw-utils" version = "0.11.0" authors = ["Ethan Frey "] edition = "2018" From 0c8cdca9b9fc6b8b70f7214d523adacc5f37ef10 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 22 Dec 2021 23:03:58 +0100 Subject: [PATCH 099/631] Fix linting issues --- contracts/cw1-whitelist-ng/src/contract.rs | 2 +- contracts/cw1-whitelist/src/contract.rs | 2 +- contracts/cw1155-base/src/contract.rs | 8 ++++---- contracts/cw20-atomic-swap/src/state.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/cw1-whitelist-ng/src/contract.rs b/contracts/cw1-whitelist-ng/src/contract.rs index d1b89c619..301b20c96 100644 --- a/contracts/cw1-whitelist-ng/src/contract.rs +++ b/contracts/cw1-whitelist-ng/src/contract.rs @@ -19,7 +19,7 @@ const CONTRACT_NAME: &str = "crates.io:cw1-whitelist"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); pub fn validate_admins(api: &dyn Api, admins: &[String]) -> StdResult> { - admins.iter().map(|addr| api.addr_validate(&addr)).collect() + admins.iter().map(|addr| api.addr_validate(addr)).collect() } impl Cw1WhitelistContract { diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index c786b53d6..c7c8784fb 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -36,7 +36,7 @@ pub fn instantiate( } pub fn map_validate(api: &dyn Api, admins: &[String]) -> StdResult> { - admins.iter().map(|addr| api.addr_validate(&addr)).collect() + admins.iter().map(|addr| api.addr_validate(addr)).collect() } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 611d3e41c..761b34094 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -133,7 +133,7 @@ fn check_can_approve(deps: Deps, env: &Env, owner: &Addr, operator: &Addr) -> St return Ok(true); } // operator can approve - let op = APPROVES.may_load(deps.storage, (&owner, &operator))?; + let op = APPROVES.may_load(deps.storage, (owner, operator))?; Ok(match op { Some(ex) => !ex.is_expired(&env.block), None => false, @@ -325,13 +325,13 @@ pub fn execute_batch_mint( let mut rsp = Response::default(); for (token_id, amount) in batch.iter() { - let event = execute_transfer_inner(&mut deps, None, Some(&to_addr), &token_id, *amount)?; + let event = execute_transfer_inner(&mut deps, None, Some(&to_addr), token_id, *amount)?; event.add_attributes(&mut rsp); // insert if not exist - if !TOKENS.has(deps.storage, &token_id) { + if !TOKENS.has(deps.storage, token_id) { // we must save some valid data here - TOKENS.save(deps.storage, &token_id, &String::new())?; + TOKENS.save(deps.storage, token_id, &String::new())?; } } diff --git a/contracts/cw20-atomic-swap/src/state.rs b/contracts/cw20-atomic-swap/src/state.rs index 0a1202630..de231bd74 100644 --- a/contracts/cw20-atomic-swap/src/state.rs +++ b/contracts/cw20-atomic-swap/src/state.rs @@ -19,7 +19,7 @@ pub struct AtomicSwap { impl AtomicSwap { pub fn is_expired(&self, block: &BlockInfo) -> bool { - self.expires.is_expired(&block) + self.expires.is_expired(block) } } From c662f2253e46eda21a3b1f3b3013d981951a7adc Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 09:52:02 +0100 Subject: [PATCH 100/631] Fix cw-utils README entry --- MIGRATING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index c8da916c3..a84f80008 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -8,7 +8,7 @@ This guide lists API changes between *cw-plus* major releases. - Rename cw0 to utils [\#471](https://github.com/CosmWasm/cw-plus/issues/471) / Cw0 rename [\#508](https://github.com/CosmWasm/cw-plus/pull/508) -The `cw0` package was renamed to `utils`. The required changes are straightforward: +The `cw0` package was renamed to `cw-utils`. The required changes are straightforward: ```diff diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml diff --git a/README.md b/README.md index 6e088d295..6f5ff52d3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ | cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | | cw-multi-test | [![cw-multi-test on crates.io](https://img.shields.io/crates/v/cw-multi-test.svg)](https://crates.io/crates/cw-multi-test) | [![Docs](https://docs.rs/cw-multi-test/badge.svg)](https://docs.rs/cw-multi-test) | | cw-storage-plus | [![cw-storage-plus on crates.io](https://img.shields.io/crates/v/cw-storage-plus.svg)](https://crates.io/crates/cw-storage-plus) | [![Docs](https://docs.rs/cw-storage-plus/badge.svg)](https://docs.rs/cw-storage-plus) | -| utils | [![utils on crates.io](https://img.shields.io/crates/v/utils.svg)](https://crates.io/crates/utils) | [![Docs](https://docs.rs/utils/badge.svg)](https://docs.rs/utils) | +| cw-utils | [![cw-utils on crates.io](https://img.shields.io/crates/v/cw-utils.svg)](https://crates.io/crates/cw-utils) | [![Docs](https://docs.rs/cw-utils/badge.svg)](https://docs.rs/cw-utils) | | Contracts | Download | Docs | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------| From 919cd5b1e08327af420b34ebf53c8e181286dfd9 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Dec 2021 11:26:41 +0100 Subject: [PATCH 101/631] Adjust order of publishing to handle new deps --- scripts/publish.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 74b2c98f4..ff3f1719b 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -8,9 +8,12 @@ STORAGE_PACKAGES="storage-plus" BASE_PACKAGES="utils" ALL_PACKAGES="controllers cw1 cw2 cw3 cw4 cw20 cw1155 multi-test" +# This is imported by cw3-fixed-multisig, which is imported by cw3-flex-multisig +# need to make a separate category to remove race conditions +CW20_BASE="cw20-base" # these are imported by other contracts -BASE_CONTRACTS="cw1-whitelist cw4-group cw20-base" -ALL_CONTRACTS="cw1-subkeys cw3-fixed-multisig cw3-flex-multisig cw4-stake cw20-atomic-swap cw20-bonding cw20-escrow cw20-ics20 cw20-staking cw1155-base" +BASE_CONTRACTS="cw1-whitelist cw4-group cw3-fixed-multisig " +ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-atomic-swap cw20-bonding cw20-escrow cw20-ics20 cw20-staking cw1155-base" SLEEP_TIME=30 @@ -46,10 +49,23 @@ for pack in $ALL_PACKAGES; do ) done + # wait for these to be processed on crates.io echo "Waiting for publishing all packages" sleep $SLEEP_TIME +for cont in CW20_BASE; do + ( + cd "contracts/$cont" + echo "Publishing $cont" + cargo publish + ) +done + +# wait for these to be processed on crates.io +echo "Waiting for publishing cw20 base" +sleep $SLEEP_TIME + for cont in $BASE_CONTRACTS; do ( cd "contracts/$cont" @@ -59,7 +75,7 @@ for cont in $BASE_CONTRACTS; do done # wait for these to be processed on crates.io -echo "Waiting for publishing base packages" +echo "Waiting for publishing base contracts" sleep $SLEEP_TIME for cont in $ALL_CONTRACTS; do From fb94db8c740e4458f9ccf3fd2d43afce6cb54f07 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 10:04:48 +0100 Subject: [PATCH 102/631] Change breaking changes migration order --- MIGRATING.md | 92 ++++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index a84f80008..fa9df0a16 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -6,6 +6,52 @@ This guide lists API changes between *cw-plus* major releases. ### Breaking Issues / PRs +- Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) / + Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) + +As part of range iterators revamping, we fixed the order of signed integer keys. You shouldn't change anything in your +code base for this, but if you were using signed keys and relying on their ordering, that has now changed for the better. +Take into account also that **the internal representation of signed integer keys has changed**. So, if you +have data stored under signed integer keys you would need to **migrate it**, or recreate it under the new representation. + +As part of this, a couple helpers for handling int keys serialization and deserialization were introduced: +- `from_cw_bytes` Integer (signed and unsigned) values deserialization. +- `to_cw_bytes` - Integer (signed and unsigned) values serialization. + +You shouldn't need these, except when manually handling raw integer keys serialization / deserialization. + +Migration code example: +```rust +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + let version = get_contract_version(deps.storage)?; + if version.contract != CONTRACT_NAME { + return Err(ContractError::CannotMigrate { + previous_contract: version.contract, + }); + } + // Original map + signed_int_map: Map = Map::new("signed_int_map"); + // New map + signed_int_map_new: Map = Map::new("signed_int_map-v2"); + + signed_int_map + .range_raw(deps.storage, None, None, Order::Ascending) + .map(|(k, v)| { + let signed = i8::from_be_bytes(k); + signed_int_map_new.save(deps.storage, signed, v); + }) + .collect()?; + + // Code to remove the old map keys + ... + + Ok(Response::default()) +} +``` + +--- + - Rename cw0 to utils [\#471](https://github.com/CosmWasm/cw-plus/issues/471) / Cw0 rename [\#508](https://github.com/CosmWasm/cw-plus/pull/508) The `cw0` package was renamed to `cw-utils`. The required changes are straightforward: @@ -193,52 +239,6 @@ index 022a4504..c7a3bb9d 100644 --- -- Incorrect I32Key Index Ordering [\#489](https://github.com/CosmWasm/cw-plus/issues/489) / -Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) - -As part of range iterators revamping, we fixed the order of signed integer keys. You shouldn't change anything in your -code base for this, but if you were using signed keys and relying on their ordering, that has now changed for the better. -Take into account also that **the internal representation of signed integer keys has changed**. So, if you -have data stored under signed integer keys you would need to **migrate it**, or recreate it under the new representation. - -As part of this, a couple helpers for handling int keys serialization and deserialization were introduced: - - `from_cw_bytes` Integer (signed and unsigned) values deserialization. - - `to_cw_bytes` - Integer (signed and unsigned) values serialization. - -You shouldn't need these, except when manually handling raw integer keys serialization / deserialization. - -Migration code example: -```rust -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let version = get_contract_version(deps.storage)?; - if version.contract != CONTRACT_NAME { - return Err(ContractError::CannotMigrate { - previous_contract: version.contract, - }); - } - // Original map - signed_int_map: Map = Map::new("signed_int_map"); - // New map - signed_int_map_new: Map = Map::new("signed_int_map-v2"); - - signed_int_map - .range_raw(deps.storage, None, None, Order::Ascending) - .map(|(k, v)| { - let signed = i8::from_be_bytes(k); - signed_int_map_new.save(deps.storage, signed, v); - }) - .collect()?; - - // Code to remove the old map keys - ... - - Ok(Response::default()) -} -``` - ---- - - `cw3-fixed-multisig` requires threshold during instantiation instead of `required_weight` parameter `Threshold` type was moved to `packages/utils` along with surrounding implementations like `ThresholdResponse` etc. From 35a987e84017727042b2ff4a1c6f97d9d882ca26 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 10:51:55 +0100 Subject: [PATCH 103/631] Add old IntKey types to allow migration --- packages/storage-plus/src/de_old.rs | 106 ++++++++++++++++++++++++++ packages/storage-plus/src/keys_old.rs | 88 +++++++++++++++++++++ packages/storage-plus/src/lib.rs | 2 + 3 files changed, 196 insertions(+) create mode 100644 packages/storage-plus/src/de_old.rs create mode 100644 packages/storage-plus/src/keys_old.rs diff --git a/packages/storage-plus/src/de_old.rs b/packages/storage-plus/src/de_old.rs new file mode 100644 index 000000000..e8c5f529d --- /dev/null +++ b/packages/storage-plus/src/de_old.rs @@ -0,0 +1,106 @@ +use std::array::TryFromSliceError; +use std::convert::TryInto; + +use cosmwasm_std::{StdError, StdResult}; + +use crate::de::KeyDeserialize; +use crate::keys_old::IntKeyOld; + +macro_rules! intkey_old_de { + (for $($t:ty),+) => { + $(impl KeyDeserialize for IntKeyOld<$t> { + type Output = $t; + + #[inline(always)] + fn from_vec(value: Vec) -> StdResult { + Ok(<$t>::from_be_bytes(value.as_slice().try_into() + .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) + } + })* + } +} + +intkey_old_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); + +#[cfg(test)] +mod test { + use super::*; + use crate::keys_old::IntKeyOld; + + #[test] + fn deserialize_integer_old_works() { + assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); + assert_eq!(>::from_slice(&[127]).unwrap(), 127i8); + assert_eq!(>::from_slice(&[128]).unwrap(), -128i8); + + assert_eq!(>::from_slice(&[1, 0]).unwrap(), 256u16); + assert_eq!(>::from_slice(&[128, 0]).unwrap(), -32768i16); + assert_eq!(>::from_slice(&[127, 255]).unwrap(), 32767i16); + + assert_eq!( + >::from_slice(&[1, 0, 0, 0]).unwrap(), + 16777216u32 + ); + assert_eq!( + >::from_slice(&[128, 0, 0, 0]).unwrap(), + -2147483648i32 + ); + assert_eq!( + >::from_slice(&[127, 255, 255, 255]).unwrap(), + 2147483647i32 + ); + + assert_eq!( + >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + 72057594037927936u64 + ); + assert_eq!( + >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + -9223372036854775808i64 + ); + assert_eq!( + >::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), + 9223372036854775807i64 + ); + + assert_eq!( + >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + .unwrap(), + 1329227995784915872903807060280344576u128 + ); + assert_eq!( + >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + .unwrap(), + -170141183460469231731687303715884105728i128 + ); + assert_eq!( + >::from_slice(&[ + 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ]) + .unwrap(), + 170141183460469231731687303715884105727i128 + ); + assert_eq!( + >::from_slice(&[ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ]) + .unwrap(), + -1i128, + ); + } + + #[test] + fn deserialize_broken_integer_old_errs() { + // One byte less fails + assert!(matches!( + >::from_slice(&[1]).err(), + Some(StdError::GenericErr { .. }) + )); + + // More bytes fails too + assert!(matches!( + >::from_slice(&[1, 2]).err(), + Some(StdError::GenericErr { .. }) + )); + } +} diff --git a/packages/storage-plus/src/keys_old.rs b/packages/storage-plus/src/keys_old.rs new file mode 100644 index 000000000..0726f068d --- /dev/null +++ b/packages/storage-plus/src/keys_old.rs @@ -0,0 +1,88 @@ +use crate::de::KeyDeserialize; +use crate::keys::Key; +use crate::{Endian, Prefixer, PrimaryKey}; +use std::marker::PhantomData; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct IntKeyOld { + pub wrapped: Vec, + pub data: PhantomData, +} + +impl IntKeyOld { + pub fn new(val: T) -> Self { + IntKeyOld { + wrapped: val.to_be_bytes().into(), + data: PhantomData, + } + } +} + +impl From for IntKeyOld { + fn from(val: T) -> Self { + IntKeyOld::new(val) + } +} + +impl From> for IntKeyOld { + fn from(wrap: Vec) -> Self { + IntKeyOld { + wrapped: wrap, + data: PhantomData, + } + } +} + +impl From> for Vec { + fn from(k: IntKeyOld) -> Vec { + k.wrapped + } +} + +// this auto-implements PrimaryKey for all the IntKeyOld types +impl<'a, T: Endian + Clone> PrimaryKey<'a> for IntKeyOld +where + IntKeyOld: KeyDeserialize, +{ + type Prefix = (); + type SubPrefix = (); + type Suffix = Self; + type SuperSuffix = Self; + + fn key(&self) -> Vec { + self.wrapped.key() + } +} + +// this auto-implements Prefixer for all the IntKey types +impl<'a, T: Endian> Prefixer<'a> for IntKeyOld { + fn prefix(&self) -> Vec { + self.wrapped.prefix() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn u64key_old_works() { + let k: IntKeyOld = 134u64.into(); + let path = k.key(); + assert_eq!(1, path.len()); + assert_eq!(134u64.to_be_bytes(), path[0].as_ref()); + } + + #[test] + fn i32key_old_works() { + let k: IntKeyOld = 4242i32.into(); + let path = k.key(); + assert_eq!(1, path.len()); + assert_eq!(4242i32.to_be_bytes(), path[0].as_ref()); + + // let k: IntKeyOld = -4242i32.into(); + // let path = k.key(); + // assert_eq!(1, path.len()); + // assert_eq!((-4242i32).to_be_bytes(), path[0].as_ref()); + } +} diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 77665e2f7..7fa68106f 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -1,4 +1,5 @@ mod de; +mod de_old; mod endian; mod helpers; mod indexed_map; @@ -8,6 +9,7 @@ mod int_key; mod item; mod iter_helpers; mod keys; +mod keys_old; mod map; mod path; mod prefix; From f6564ca3ce843d04d098fb6b1cd7609b3e660dbe Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 11:24:34 +0100 Subject: [PATCH 104/631] Add signed int key `Map` migration test / example --- packages/storage-plus/src/map.rs | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 5bb9e91e5..a04015465 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -255,6 +255,7 @@ mod test { use cosmwasm_std::{Order, StdResult}; use crate::int_key::CwIntKey; + use crate::keys_old::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -266,6 +267,8 @@ mod test { #[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: Map = Map::new("signed_id"); const ALLOWANCE: Map<(&[u8], &[u8]), u64> = Map::new("allow"); @@ -635,6 +638,77 @@ mod test { assert_eq!(all, vec![(50, data3)]); } + #[test] + #[cfg(feature = "iterator")] + fn range_signed_integer_key_migration() { + let mut store = MockStorage::new(); + + // save and load three keys with the old format + let data = Data { + name: "John".to_string(), + age: 32, + }; + SIGNED_ID_OLD + .save(&mut store, IntKeyOld::::from(-1234), &data) + .unwrap(); + + let data2 = Data { + name: "Jim".to_string(), + age: 44, + }; + SIGNED_ID_OLD + .save(&mut store, IntKeyOld::::from(-56), &data2) + .unwrap(); + + let data3 = Data { + name: "Jules".to_string(), + age: 55, + }; + SIGNED_ID_OLD + .save(&mut store, IntKeyOld::::from(50), &data3) + .unwrap(); + + // obtain all current keys + let current = SIGNED_ID_OLD + .range(&store, None, None, Order::Ascending) + .collect::>>() + .unwrap(); + // confirm wrong current order + assert_eq!( + current, + vec![ + (50, data3.clone()), + (-1234, data.clone()), + (-56, data2.clone()) + ] + ); + + // remove old entries + for (k, _) in current.iter() { + SIGNED_ID_OLD.remove(&mut store, IntKeyOld::::from(*k)); + } + + // confirm map is empty + assert!(SIGNED_ID_OLD + .range(&store, None, None, Order::Ascending) + .collect::>>() + .unwrap() + .is_empty()); + + // save in new format + for (k, v) in current.iter() { + SIGNED_ID.save(&mut store, *k, v).unwrap(); + } + + // obtain new keys + let new = SIGNED_ID + .range(&store, None, None, Order::Ascending) + .collect::>>() + .unwrap(); + // confirm new order is right + assert_eq!(new, vec![(-1234, data), (-56, data2), (50, data3)]); + } + #[test] #[cfg(feature = "iterator")] fn range_raw_composite_key() { From cfcefd03f7ea14eed49dcf458314ef6585b6d3de Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 12:23:13 +0100 Subject: [PATCH 105/631] Publish `IntKeyOld` --- packages/storage-plus/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 7fa68106f..841700f51 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -34,6 +34,7 @@ pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; pub use int_key::CwIntKey; #[allow(deprecated)] pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; +pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] From db3856205cb9616e5ff857955a6f2fc88379068b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 12:23:45 +0100 Subject: [PATCH 106/631] Update MIGRATING.md signed int keys migration code --- MIGRATING.md | 81 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index fa9df0a16..b625219fe 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -23,30 +23,65 @@ You shouldn't need these, except when manually handling raw integer keys seriali Migration code example: ```rust #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let version = get_contract_version(deps.storage)?; - if version.contract != CONTRACT_NAME { - return Err(ContractError::CannotMigrate { - previous_contract: version.contract, - }); - } +pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result { + let version: Version = CONTRACT_VERSION.parse()?; + let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?; + + if storage_version < version { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + // Do the migration // Original map - signed_int_map: Map = Map::new("signed_int_map"); - // New map - signed_int_map_new: Map = Map::new("signed_int_map-v2"); - - signed_int_map - .range_raw(deps.storage, None, None, Order::Ascending) - .map(|(k, v)| { - let signed = i8::from_be_bytes(k); - signed_int_map_new.save(deps.storage, signed, v); - }) - .collect()?; - - // Code to remove the old map keys - ... - - Ok(Response::default()) + let signed_int_map: Map, String> = Map::new("signed_int_map"); + + // New map (using a different namespace for safety. It could be the same with enough care) + let signed_int_map_new: Map = Map::new("signed_int_map-v2"); + + // Obtain all current keys (this will need to be paginated if there are many entries, + // i.e. i32 or i64 instead of i8). + // This may be gas intensive + let current = signed_int_map + .range(deps.storage, None, None, Order::Ascending) + .collect::>>()?; + + // Store length for quality control (adjust if paginated) + let current_count = current.len(); + + // Remove the old map keys + for (k, _) in current.iter() { + signed_int_map.remove(deps.storage, IntKeyOld::::from(*k)); + } + + // Save in new format + for (k, v) in current.iter() { + signed_int_map_new.save(deps.storage, *k, v)?; + } + + // Confirm old map is empty + if signed_int_map + .keys_raw(deps.storage, None, None, Order::Ascending) + .next() + .is_some() + { + return Err(StdError::generic_err("Original still not empty!").into()); + } + + // Obtain new keys, and confirm their amount. + // May be gas intensive. + let new_count = signed_int_map_new + .keys_raw(deps.storage, None, None, Order::Ascending) + .count(); + + if current_count != new_count { + return Err(StdError::generic_err(format!( + "Current ({}) and new ({}) counts differ!", + current_count, new_count + )) + .into()); + } + } + + Ok(Response::new()) } ``` From 036beb1b26c6221c35e14635a0eba9e777b49009 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 12:32:48 +0100 Subject: [PATCH 107/631] Add negative integer int key check --- packages/storage-plus/src/keys_old.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/keys_old.rs b/packages/storage-plus/src/keys_old.rs index 0726f068d..d864153e2 100644 --- a/packages/storage-plus/src/keys_old.rs +++ b/packages/storage-plus/src/keys_old.rs @@ -80,9 +80,9 @@ mod test { assert_eq!(1, path.len()); assert_eq!(4242i32.to_be_bytes(), path[0].as_ref()); - // let k: IntKeyOld = -4242i32.into(); - // let path = k.key(); - // assert_eq!(1, path.len()); - // assert_eq!((-4242i32).to_be_bytes(), path[0].as_ref()); + let k: IntKeyOld = IntKeyOld::::from(-4242i32); + let path = k.key(); + assert_eq!(1, path.len()); + assert_eq!((-4242i32).to_be_bytes(), path[0].as_ref()); } } From 330c14bcb66407ed1eeb2f82da84a6732f0a0cb3 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 23 Dec 2021 14:13:50 +0100 Subject: [PATCH 108/631] Improve migration code examples --- MIGRATING.md | 6 +++--- packages/storage-plus/src/map.rs | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index b625219fe..ea5b67c8d 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -49,12 +49,12 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result::from(*k)); + signed_int_map.remove(deps.storage, (*k).into()); } // Save in new format - for (k, v) in current.iter() { - signed_int_map_new.save(deps.storage, *k, v)?; + for (k, v) in current.into_iter() { + signed_int_map_new.save(deps.storage, k, &v)?; } // Confirm old map is empty diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index a04015465..94d78bdcd 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -685,19 +685,18 @@ mod test { // remove old entries for (k, _) in current.iter() { - SIGNED_ID_OLD.remove(&mut store, IntKeyOld::::from(*k)); + SIGNED_ID_OLD.remove(&mut store, (*k).into()); } // confirm map is empty assert!(SIGNED_ID_OLD .range(&store, None, None, Order::Ascending) - .collect::>>() - .unwrap() - .is_empty()); + .next() + .is_none()); // save in new format - for (k, v) in current.iter() { - SIGNED_ID.save(&mut store, *k, v).unwrap(); + for (k, v) in current.into_iter() { + SIGNED_ID.save(&mut store, k, &v).unwrap(); } // obtain new keys From 5101d722a1f03305403bb8ce8202f9370f308b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Fri, 24 Dec 2021 17:27:49 +0300 Subject: [PATCH 109/631] Add scheduled util --- packages/utils/src/lib.rs | 1 + packages/utils/src/scheduled.rs | 63 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 packages/utils/src/scheduled.rs diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index c39b1005e..28ce11734 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -4,6 +4,7 @@ mod expiration; mod pagination; mod parse_reply; mod payment; +mod scheduled; mod threshold; pub use pagination::{ diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs new file mode 100644 index 000000000..5e6d5617b --- /dev/null +++ b/packages/utils/src/scheduled.rs @@ -0,0 +1,63 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::Duration; +use cosmwasm_std::{BlockInfo, StdError, StdResult, Timestamp}; +use std::cmp::Ordering; +use std::fmt; +use std::ops::Add; + +#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] +#[serde(rename_all = "snake_case")] +/// Scheduled represents a point in time when an event happens. +/// It can compare with a BlockInfo and will return is_triggered() == true +/// once the condition is hit (and for every block in the future) +pub enum Scheduled { + /// AtHeight will schedule when `env.block.height` >= height + AtHeight(u64), + /// AtTime will schedule when `env.block.time` >= time + AtTime(Timestamp), +} + +impl fmt::Display for Scheduled { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Scheduled::AtHeight(height) => write!(f, "scheduled height: {}", height), + Scheduled::AtTime(time) => write!(f, "scheduled time: {}", time), + } + } +} + +impl Scheduled { + pub fn is_triggered(&self, block: &BlockInfo) -> bool { + match self { + Scheduled::AtHeight(height) => block.height >= *height, + Scheduled::AtTime(time) => block.time >= *time, + } + } +} + +impl Add for Scheduled { + type Output = StdResult; + + fn add(self, duration: Duration) -> StdResult { + match (self, duration) { + (Scheduled::AtTime(t), Duration::Time(delta)) => { + Ok(Scheduled::AtTime(t.plus_seconds(delta))) + } + (Scheduled::AtHeight(h), Duration::Height(delta)) => Ok(Scheduled::AtHeight(h + delta)), + _ => Err(StdError::generic_err("Cannot add height and time")), + } + } +} + +impl PartialOrd for Scheduled { + fn partial_cmp(&self, other: &Scheduled) -> Option { + match (self, other) { + // compare if both height or both time + (Scheduled::AtHeight(h1), Scheduled::AtHeight(h2)) => Some(h1.cmp(h2)), + (Scheduled::AtTime(t1), Scheduled::AtTime(t2)) => Some(t1.cmp(t2)), + _ => None, + } + } +} From 56ee692ba3280847f62d85d607cf7ef32101ba66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Fri, 24 Dec 2021 17:37:12 +0300 Subject: [PATCH 110/631] Linter happy --- packages/utils/src/lib.rs | 1 + packages/utils/src/scheduled.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index 28ce11734..4687606d9 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -21,3 +21,4 @@ pub use threshold::{Threshold, ThresholdError, ThresholdResponse}; pub use crate::balance::NativeBalance; pub use crate::event::Event; pub use crate::expiration::{Duration, Expiration, DAY, HOUR, WEEK}; +pub use crate::scheduled::Scheduled; diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs index 5e6d5617b..81a4c049e 100644 --- a/packages/utils/src/scheduled.rs +++ b/packages/utils/src/scheduled.rs @@ -29,6 +29,7 @@ impl fmt::Display for Scheduled { } impl Scheduled { + #[allow(dead_code)] pub fn is_triggered(&self, block: &BlockInfo) -> bool { match self { Scheduled::AtHeight(height) => block.height >= *height, From 1dd531d66c7164c73c2373ab402facd57b382679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Sun, 26 Dec 2021 19:08:27 +0300 Subject: [PATCH 111/631] cw-storage-plus: Expose keys::Key --- packages/storage-plus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 841700f51..ad6eb0fae 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -33,7 +33,7 @@ pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; // TODO: Remove along with `IntKey` pub use int_key::CwIntKey; #[allow(deprecated)] -pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; +pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key, Key}; pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; From 37af252f3f19088d36b1295486d618c7ad81fc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Sun, 26 Dec 2021 19:09:31 +0300 Subject: [PATCH 112/631] Fmt --- packages/storage-plus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index ad6eb0fae..e054879cf 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -33,7 +33,7 @@ pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; // TODO: Remove along with `IntKey` pub use int_key::CwIntKey; #[allow(deprecated)] -pub use keys::{Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key, Key}; +pub use keys::{Key, Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; From 0c1237c2e112a7b50de1d72bf38bb48a01dbc8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 28 Dec 2021 13:06:18 +0300 Subject: [PATCH 113/631] Test addition and compare --- packages/utils/src/scheduled.rs | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs index 81a4c049e..6b7f26227 100644 --- a/packages/utils/src/scheduled.rs +++ b/packages/utils/src/scheduled.rs @@ -62,3 +62,59 @@ impl PartialOrd for Scheduled { } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn compare_schedules() { + // matching pairs + assert!(Scheduled::AtHeight(5) < Scheduled::AtHeight(10)); + assert!(Scheduled::AtHeight(8) > Scheduled::AtHeight(7)); + assert!( + Scheduled::AtTime(Timestamp::from_seconds(555)) + < Scheduled::AtTime(Timestamp::from_seconds(777)) + ); + assert!( + Scheduled::AtTime(Timestamp::from_seconds(86)) + < Scheduled::AtTime(Timestamp::from_seconds(100)) + ); + + // what happens for the uncomparables?? all compares are false + assert_eq!( + None, + Scheduled::AtTime(Timestamp::from_seconds(1000)) + .partial_cmp(&Scheduled::AtHeight(230)) + ); + assert_eq!( + Scheduled::AtTime(Timestamp::from_seconds(1000)) + .partial_cmp(&Scheduled::AtHeight(230)), + None + ); + assert_eq!( + Scheduled::AtTime(Timestamp::from_seconds(1000)) + .partial_cmp(&Scheduled::AtHeight(230)), + None + ); + assert!(!(Scheduled::AtTime(Timestamp::from_seconds(1000)) == Scheduled::AtHeight(230))); + } + + #[test] + fn schedule_addition() { + // height + let end = Scheduled::AtHeight(12345) + Duration::Height(400); + assert_eq!(end.unwrap(), Scheduled::AtHeight(12745)); + + // time + let end = Scheduled::AtTime(Timestamp::from_seconds(55544433)) + Duration::Time(40300); + assert_eq!( + end.unwrap(), + Scheduled::AtTime(Timestamp::from_seconds(55584733)) + ); + + // mismatched + let end = Scheduled::AtHeight(12345) + Duration::Time(1500); + end.unwrap_err(); + } +} From 37a2fe2b90193d13b4d4d07e176cbcc94a857336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 28 Dec 2021 13:25:43 +0300 Subject: [PATCH 114/631] Fmt --- packages/utils/src/scheduled.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs index 6b7f26227..c8c6ca4bb 100644 --- a/packages/utils/src/scheduled.rs +++ b/packages/utils/src/scheduled.rs @@ -84,17 +84,14 @@ mod test { // what happens for the uncomparables?? all compares are false assert_eq!( None, - Scheduled::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Scheduled::AtHeight(230)) + Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)) ); assert_eq!( - Scheduled::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Scheduled::AtHeight(230)), + Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)), None ); assert_eq!( - Scheduled::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Scheduled::AtHeight(230)), + Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)), None ); assert!(!(Scheduled::AtTime(Timestamp::from_seconds(1000)) == Scheduled::AtHeight(230))); From 57aa23a6315e1be5d5efd6e6a7031a9987c910d2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 17:40:21 +0100 Subject: [PATCH 115/631] Assert non-empty send/burn/mint in multitest bank module --- packages/multi-test/src/bank.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs index 33b540784..30b047737 100644 --- a/packages/multi-test/src/bank.rs +++ b/packages/multi-test/src/bank.rs @@ -84,6 +84,7 @@ impl BankKeeper { to_address: Addr, amount: Vec, ) -> AnyResult<()> { + let amount = self.normalize_amount(amount)?; let b = self.get_balance(bank_storage, &to_address)?; let b = NativeBalance(b) + NativeBalance(amount); self.set_balance(bank_storage, &to_address, b.into_vec()) @@ -95,10 +96,21 @@ impl BankKeeper { from_address: Addr, amount: Vec, ) -> AnyResult<()> { + let amount = self.normalize_amount(amount)?; let a = self.get_balance(bank_storage, &from_address)?; let a = (NativeBalance(a) - amount)?; self.set_balance(bank_storage, &from_address, a.into_vec()) } + + /// Filters out all 0 value coins and returns an error if the resulting Vec is empty + fn normalize_amount(&self, amount: Vec) -> AnyResult> { + let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); + if res.is_empty() { + bail!("Cannot transfer empty coins amount") + } else { + Ok(res) + } + } } fn coins_to_string(coins: &[Coin]) -> String { From 9c4c2745c5b96959e90ccfb0d5997b42aa420d59 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 17:48:21 +0100 Subject: [PATCH 116/631] Test 0 values return errors --- packages/multi-test/src/bank.rs | 75 +++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs index 30b047737..17cea14fa 100644 --- a/packages/multi-test/src/bank.rs +++ b/packages/multi-test/src/bank.rs @@ -395,4 +395,79 @@ mod test { .unwrap_err(); assert!(matches!(err.downcast().unwrap(), StdError::Overflow { .. })); } + + #[test] + fn fail_on_zero_values() { + let api = MockApi::default(); + let mut store = MockStorage::new(); + let block = mock_env().block; + let router = MockRouter::default(); + + let owner = Addr::unchecked("owner"); + let rcpt = Addr::unchecked("recipient"); + let init_funds = vec![coin(5000, "atom"), coin(100, "eth")]; + + // set money + let bank = BankKeeper::new(); + bank.init_balance(&mut store, &owner, init_funds).unwrap(); + + // can send normal amounts + let msg = BankMsg::Send { + to_address: rcpt.to_string(), + amount: coins(100, "atom"), + }; + bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) + .unwrap(); + + // fails send on no coins + let msg = BankMsg::Send { + to_address: rcpt.to_string(), + amount: vec![], + }; + bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) + .unwrap_err(); + + // fails send on 0 coins + let msg = BankMsg::Send { + to_address: rcpt.to_string(), + amount: coins(0, "atom"), + }; + bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) + .unwrap_err(); + + // fails burn on no coins + let msg = BankMsg::Burn { amount: vec![] }; + bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) + .unwrap_err(); + + // fails burn on 0 coins + let msg = BankMsg::Burn { + amount: coins(0, "atom"), + }; + bank.execute(&api, &mut store, &router, &block, owner, msg) + .unwrap_err(); + + // can mint via sudo + let msg = BankSudo::Mint { + to_address: rcpt.to_string(), + amount: coins(4321, "atom"), + }; + bank.sudo(&api, &mut store, &router, &block, msg).unwrap(); + + // mint fails with 0 tokens + let msg = BankSudo::Mint { + to_address: rcpt.to_string(), + amount: coins(0, "atom"), + }; + bank.sudo(&api, &mut store, &router, &block, msg) + .unwrap_err(); + + // mint fails with no tokens + let msg = BankSudo::Mint { + to_address: rcpt.to_string(), + amount: vec![], + }; + bank.sudo(&api, &mut store, &router, &block, msg) + .unwrap_err(); + } } From 62653b83043b945175a7f9b7b7cba63d4f2374c9 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 17:51:29 +0100 Subject: [PATCH 117/631] Set version: 0.11.1 --- Cargo.lock | 48 ++++++++++++------------ contracts/cw1-subkeys/Cargo.toml | 14 +++---- contracts/cw1-whitelist-ng/Cargo.toml | 14 +++---- contracts/cw1-whitelist/Cargo.toml | 12 +++--- contracts/cw1155-base/Cargo.toml | 10 ++--- contracts/cw20-atomic-swap/Cargo.toml | 10 ++--- contracts/cw20-base/Cargo.toml | 10 ++--- contracts/cw20-bonding/Cargo.toml | 12 +++--- contracts/cw20-escrow/Cargo.toml | 14 +++---- contracts/cw20-ics20/Cargo.toml | 10 ++--- contracts/cw20-merkle-airdrop/Cargo.toml | 8 ++-- contracts/cw20-staking/Cargo.toml | 14 +++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 ++++---- contracts/cw3-flex-multisig/Cargo.toml | 18 ++++----- contracts/cw4-group/Cargo.toml | 12 +++--- contracts/cw4-stake/Cargo.toml | 14 +++---- packages/controllers/Cargo.toml | 6 +-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +- packages/cw2/Cargo.toml | 4 +- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 4 +- packages/multi-test/Cargo.toml | 6 +-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +- 26 files changed, 138 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74175f326..cf9ab4438 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,7 +241,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -253,7 +253,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.11.0" +version = "0.11.1" dependencies = [ "anyhow", "cosmwasm-std", @@ -270,7 +270,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-std", "schemars", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -291,7 +291,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -318,7 +318,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.11.0" +version = "0.11.1" dependencies = [ "anyhow", "assert_matches", @@ -337,7 +337,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.11.0" +version = "0.11.1" dependencies = [ "anyhow", "assert_matches", @@ -356,7 +356,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -367,7 +367,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -392,7 +392,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "cw20-atomic-swap" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -420,7 +420,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "cw20-bonding" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -454,7 +454,7 @@ dependencies = [ [[package]] name = "cw20-escrow" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -471,7 +471,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -504,7 +504,7 @@ dependencies = [ [[package]] name = "cw20-staking" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -521,7 +521,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -550,7 +550,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -569,7 +569,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -596,7 +596,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 5c487ff9c..7869846bc 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw1 = { path = "../../packages/cw1", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw1 = { path = "../../packages/cw1", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.1", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index d03d5d474..bf65ba592 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.11.0" +version = "0.11.1" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw1 = { path = "../../packages/cw1", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw1 = { path = "../../packages/cw1", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 4ca281d08..bc60dbb54 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw1 = { path = "../../packages/cw1", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw1 = { path = "../../packages/cw1", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 16ccfc160..9890e29c6 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.11.0" +version = "0.11.1" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw1155 = { path = "../../packages/cw1155", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-atomic-swap/Cargo.toml b/contracts/cw20-atomic-swap/Cargo.toml index 3f9fc0797..da1745131 100644 --- a/contracts/cw20-atomic-swap/Cargo.toml +++ b/contracts/cw20-atomic-swap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-atomic-swap" -version = "0.11.0" +version = "0.11.1" authors = ["Mauro Lacy "] edition = "2018" description = "Implementation of Atomic Swaps" @@ -15,11 +15,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index ae494f080..070e6c918 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-bonding/Cargo.toml b/contracts/cw20-bonding/Cargo.toml index fea0d5065..2c4508a70 100644 --- a/contracts/cw20-bonding/Cargo.toml +++ b/contracts/cw20-bonding/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-bonding" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement basic bonding curve to issue cw20 tokens" @@ -20,11 +20,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.11.0", features = ["library"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw20-base = { path = "../../contracts/cw20-base", version = "0.11.1", features = ["library"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3", default-features = false, features = ["staking"] } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-escrow/Cargo.toml b/contracts/cw20-escrow/Cargo.toml index a41fbc36a..1f5f93afa 100644 --- a/contracts/cw20-escrow/Cargo.toml +++ b/contracts/cw20-escrow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-escrow" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an escrow that accepts CosmWasm-20 tokens as well as native tokens" @@ -18,16 +18,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } -cw20-base = { path = "../cw20-base", version = "0.11.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } +cw20-base = { path = "../cw20-base", version = "0.11.1", features = ["library"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index b268ea558..61875dcdd 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,11 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-merkle-airdrop/Cargo.toml b/contracts/cw20-merkle-airdrop/Cargo.toml index ba108b805..fa64e4f28 100644 --- a/contracts/cw20-merkle-airdrop/Cargo.toml +++ b/contracts/cw20-merkle-airdrop/Cargo.toml @@ -19,11 +19,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-staking/Cargo.toml b/contracts/cw20-staking/Cargo.toml index 75d2c7123..0275d354b 100644 --- a/contracts/cw20-staking/Cargo.toml +++ b/contracts/cw20-staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-staking" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement simple staking derivatives as a cw20 token" @@ -20,13 +20,13 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.11.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } +cw20-base = { path = "../../contracts/cw20-base", version = "0.11.1", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 445e8d66a..bc2649280 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw3 = { path = "../../packages/cw3", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw3 = { path = "../../packages/cw3", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } -cw20-base = { path = "../cw20-base", version = "0.11.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw20-base = { path = "../cw20-base", version = "0.11.1", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 47b517f22..1fc778bd9 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw3 = { path = "../../packages/cw3", version = "0.11.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.11.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw3 = { path = "../../packages/cw3", version = "0.11.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.11.1", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw4-group = { path = "../cw4-group", version = "0.11.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.0" } +cw4-group = { path = "../cw4-group", version = "0.11.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 1918a243e..8f6859053 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw4 = { path = "../../packages/cw4", version = "0.11.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw4 = { path = "../../packages/cw4", version = "0.11.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 1709658ee..c36847346 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw2 = { path = "../../packages/cw2", version = "0.11.0" } -cw4 = { path = "../../packages/cw4", version = "0.11.0" } -cw20 = { path = "../../packages/cw20", version = "0.11.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw4 = { path = "../../packages/cw4", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index df6e54b45..b2fe7dabd 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3" } -cw-utils = { path = "../utils", version = "0.11.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.11.0" } +cw-utils = { path = "../utils", version = "0.11.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 01cdea229..85f4a0a55 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 632249d32..4f9ded91b 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.11.0" +version = "0.11.1" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 3d3e6bb71..649eb14c9 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 95df78df0..6675eeca5 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index eddc95d4f..3f6426ff2 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } +cw-utils = { path = "../../packages/utils", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index bd428f71a..b87cfbdd6 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.11.1" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index f29bd906e..f19d84b0d 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0"} +cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1"} cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta3" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 30f622807..9eefb2040 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 7c920b592..ffc88f5a3 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.11.0" +version = "0.11.1" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } prost = "0.9" From 41f23ccded2f76e660cefdfff05f5c281732d4a4 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 18:07:58 +0100 Subject: [PATCH 118/631] Update CHANGELOG --- CHANGELOG.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f04f2e5..a835fe6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,33 @@ # Changelog +# Changelog + ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...HEAD) + +## [v0.11.1](https://github.com/CosmWasm/cw-plus/tree/v0.11.1) (2021-12-28) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.0...v0.11.1) + +**Closed issues:** + +- multitest returns error on BankMsg with 0 tokens [\#610](https://github.com/CosmWasm/cw-plus/issues/610) +- Add signed int keys migration example [\#602](https://github.com/CosmWasm/cw-plus/issues/602) +- Issue running wasm compilation out-of-the-box [\#545](https://github.com/CosmWasm/cw-plus/issues/545) + +**Merged pull requests:** + +- Assert non-empty send/burn/mint in multitest bank module [\#611](https://github.com/CosmWasm/cw-plus/pull/611) ([ethanfrey](https://github.com/ethanfrey)) +- cw-storage-plus: Expose keys::Key [\#609](https://github.com/CosmWasm/cw-plus/pull/609) ([orkunkl](https://github.com/orkunkl)) +- Implement Expired variant, Scheduled [\#606](https://github.com/CosmWasm/cw-plus/pull/606) ([orkunkl](https://github.com/orkunkl)) +- Signed int keys migrate example [\#604](https://github.com/CosmWasm/cw-plus/pull/604) ([maurolacy](https://github.com/maurolacy)) +- Adjust order of publishing to handle new deps [\#603](https://github.com/CosmWasm/cw-plus/pull/603) ([ethanfrey](https://github.com/ethanfrey)) +- Fix cw-utils README entry [\#601](https://github.com/CosmWasm/cw-plus/pull/601) ([maurolacy](https://github.com/maurolacy)) +- Rename utils to cw-utils [\#598](https://github.com/CosmWasm/cw-plus/pull/598) ([ethanfrey](https://github.com/ethanfrey)) +- Mention latest workspace optimizer version in README [\#595](https://github.com/CosmWasm/cw-plus/pull/595) ([ueco-jb](https://github.com/ueco-jb)) -## [v0.11.0](https://github.com/CosmWasm/cw-plus/tree/v0.11.0) (2021-11-22) +## [v0.11.0](https://github.com/CosmWasm/cw-plus/tree/v0.11.0) (2021-12-22) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.10.3...v0.11.0) From f45f3b31b0274bfcc73fc3195e21591186c03e53 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 18:35:47 +0100 Subject: [PATCH 119/631] Fix minor typo in publish.sh --- scripts/publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index ff3f1719b..811890132 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -54,7 +54,7 @@ done echo "Waiting for publishing all packages" sleep $SLEEP_TIME -for cont in CW20_BASE; do +for cont in $CW20_BASE; do ( cd "contracts/$cont" echo "Publishing $cont" From cec7a97d33c63645de01cbab1470ce0bd8c0528c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 18:40:20 +0100 Subject: [PATCH 120/631] Remove references to cw-tokens contracts in publish, README --- README.md | 10 ++++------ scripts/publish.sh | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6f5ff52d3..152d92557 100644 --- a/README.md +++ b/README.md @@ -26,17 +26,15 @@ | cw3-flex-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_flex_multisig.wasm) | [![Docs](https://docs.rs/cw3-flex-multisig/badge.svg)](https://docs.rs/cw3-flex-multisig) | | cw4-group | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_group.wasm) | [![Docs](https://docs.rs/cw4-group/badge.svg)](https://docs.rs/cw4-group) | | cw4-stake | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | -| cw20-atomic-swap | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_atomic_swap.wasm) | [![Docs](https://docs.rs/cw20-atomic-swap/badge.svg)](https://docs.rs/cw20-atomic-swap) | | cw20-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | -| cw20-bonding | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_bonding.wasm) | [![Docs](https://docs.rs/cw20-bonding/badge.svg)](https://docs.rs/cw20-bonding) | -| cw20-escrow | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_escrow.wasm) | [![Docs](https://docs.rs/cw20-escrow/badge.svg)](https://docs.rs/cw20-escrow) | | cw20-ics20 | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | -| cw20-staking | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_staking.wasm) | [![Docs](https://docs.rs/cw20-staking/badge.svg)](https://docs.rs/cw20-staking) | -| cw20-merkle-airdrop | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_merkle_airdrop.wasm) | [![Docs](https://docs.rs/cw20-merkle-airdrop/badge.svg)](https://docs.rs/cw20-merkle-airdrop) | | cw1155-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | -Note that `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) +Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) +and can be followed there. + +Note: most of the `cw20-*` contracts besides `cw20-base` have moved to the new [`cw-tokens` repo](https://github.com/CosmWasm/cw-tokens) and can be followed there. This is a collection of specification and contracts designed for diff --git a/scripts/publish.sh b/scripts/publish.sh index 811890132..8c4bee118 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -13,7 +13,7 @@ ALL_PACKAGES="controllers cw1 cw2 cw3 cw4 cw20 cw1155 multi-test" CW20_BASE="cw20-base" # these are imported by other contracts BASE_CONTRACTS="cw1-whitelist cw4-group cw3-fixed-multisig " -ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-atomic-swap cw20-bonding cw20-escrow cw20-ics20 cw20-staking cw1155-base" +ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-ics20 cw1155-base" SLEEP_TIME=30 From 3401ae7e172d6d44d5842bb38270bb3f8ba4620b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 18:42:06 +0100 Subject: [PATCH 121/631] Remove cw-tokens contracts from CI and Cargo.toml --- .circleci/config.yml | 143 ------------------------------------------- Cargo.toml | 20 ------ 2 files changed, 163 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7bdf9d52e..b1ac2aa51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,13 +10,8 @@ workflows: - contract_cw3_flex_multisig - contract_cw4_group - contract_cw4_stake - - contract_cw20_atomic_swap - contract_cw20_base - - contract_cw20_bonding - - contract_cw20_escrow - contract_cw20_ics20 - - contract_cw20_staking - - contract_cw20_merkle_airdrop - contract_cw1155_base - package_controllers - package_utils @@ -127,36 +122,6 @@ jobs: - target key: cargocache-cw1-whitelist-ng-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw20_atomic_swap: - docker: - - image: rust:1.53.0 - working_directory: ~/project/contracts/cw20-atomic-swap - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw20-atomic-swap-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Add wasm32 target - command: rustup target add wasm32-unknown-unknown - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw20-atomic-swap-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw3_fixed_multisig: docker: - image: rust:1.53.0 @@ -292,60 +257,6 @@ jobs: - target key: cargocache-cw20-base-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw20_bonding: - docker: - - image: rust:1.53.0 - working_directory: ~/project/contracts/cw20-bonding - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw20-bonding-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw20-bonding-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - contract_cw20_escrow: - docker: - - image: rust:1.53.0 - working_directory: ~/project/contracts/cw20-escrow - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw20-escrow-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw20-escrow-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw20_ics20: docker: - image: rust:1.53.0 @@ -373,60 +284,6 @@ jobs: - target key: cargocache-cw20-ics20-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw20_staking: - docker: - - image: rust:1.53.0 - working_directory: ~/project/contracts/cw20-staking - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw20-staking-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw20-staking-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - contract_cw20_merkle_airdrop: - docker: - - image: rust:1.53.0 - working_directory: ~/project/contracts/cw20-merkle-airdrop - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw20-merkle-airdrop-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw20-merkle-airdrop-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} - contract_cw1155_base: docker: - image: rust:1.53.0 diff --git a/Cargo.toml b/Cargo.toml index 05682fd76..6cd7a4468 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,34 +25,14 @@ incremental = false codegen-units = 1 incremental = false -[profile.release.package.cw20-atomic-swap] -codegen-units = 1 -incremental = false - [profile.release.package.cw20-base] codegen-units = 1 incremental = false -[profile.release.package.cw20-bonding] -codegen-units = 1 -incremental = false - -[profile.release.package.cw20-escrow] -codegen-units = 1 -incremental = false - [profile.release.package.cw20-ics20] codegen-units = 1 incremental = false -[profile.release.package.cw20-merkle-airdrop] -codegen-units = 1 -incremental = false - -[profile.release.package.cw20-staking] -codegen-units = 1 -incremental = false - [profile.release.package.cw1155-base] codegen-units = 1 incremental = false From c066498db73162ca8ae47e610d181c1ac5bba4a7 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 18:42:50 +0100 Subject: [PATCH 122/631] Remove contract code that moved to cw-tokens --- contracts/cw20-atomic-swap/.cargo/config | 6 - contracts/cw20-atomic-swap/Cargo.toml | 30 - contracts/cw20-atomic-swap/NOTICE | 14 - contracts/cw20-atomic-swap/README.md | 48 - contracts/cw20-atomic-swap/examples/schema.rs | 23 - contracts/cw20-atomic-swap/src/contract.rs | 745 ----- contracts/cw20-atomic-swap/src/error.rs | 32 - contracts/cw20-atomic-swap/src/lib.rs | 6 - contracts/cw20-atomic-swap/src/msg.rs | 96 - contracts/cw20-atomic-swap/src/state.rs | 78 - contracts/cw20-bonding/.cargo/config | 6 - contracts/cw20-bonding/Cargo.toml | 37 - contracts/cw20-bonding/NOTICE | 14 - contracts/cw20-bonding/README.md | 72 - contracts/cw20-bonding/examples/schema.rs | 22 - contracts/cw20-bonding/src/contract.rs | 636 ---- contracts/cw20-bonding/src/curves.rs | 357 --- contracts/cw20-bonding/src/error.rs | 18 - contracts/cw20-bonding/src/lib.rs | 7 - contracts/cw20-bonding/src/msg.rs | 145 - contracts/cw20-bonding/src/state.rs | 38 - contracts/cw20-escrow/.cargo/config | 6 - contracts/cw20-escrow/Cargo.toml | 33 - contracts/cw20-escrow/NOTICE | 14 - contracts/cw20-escrow/README.md | 46 - contracts/cw20-escrow/examples/schema.rs | 22 - contracts/cw20-escrow/src/contract.rs | 603 ---- contracts/cw20-escrow/src/error.rs | 23 - contracts/cw20-escrow/src/integration_test.rs | 151 - contracts/cw20-escrow/src/lib.rs | 7 - contracts/cw20-escrow/src/msg.rs | 123 - contracts/cw20-escrow/src/state.rs | 145 - contracts/cw20-merkle-airdrop/.cargo/config | 6 - contracts/cw20-merkle-airdrop/Cargo.toml | 35 - contracts/cw20-merkle-airdrop/NOTICE | 16 - contracts/cw20-merkle-airdrop/README.md | 105 - .../cw20-merkle-airdrop/examples/schema.rs | 23 - .../cw20-merkle-airdrop/helpers/.eslintignore | 1 - .../cw20-merkle-airdrop/helpers/.eslintrc | 6 - .../cw20-merkle-airdrop/helpers/.gitignore | 8 - .../cw20-merkle-airdrop/helpers/README.md | 47 - contracts/cw20-merkle-airdrop/helpers/bin/run | 5 - .../cw20-merkle-airdrop/helpers/bin/run.cmd | 3 - .../cw20-merkle-airdrop/helpers/package.json | 60 - .../helpers/src/airdrop.ts | 44 - .../helpers/src/commands/generateProofs.ts | 48 - .../helpers/src/commands/generateRoot.ts | 37 - .../helpers/src/commands/verifyProofs.ts | 55 - .../cw20-merkle-airdrop/helpers/src/index.ts | 1 - .../cw20-merkle-airdrop/helpers/tsconfig.json | 33 - .../cw20-merkle-airdrop/helpers/yarn.lock | 2767 ----------------- contracts/cw20-merkle-airdrop/src/contract.rs | 548 ---- contracts/cw20-merkle-airdrop/src/error.rs | 30 - contracts/cw20-merkle-airdrop/src/lib.rs | 6 - contracts/cw20-merkle-airdrop/src/msg.rs | 68 - contracts/cw20-merkle-airdrop/src/state.rs | 24 - .../testdata/airdrop_stage_1_list.json | 9 - .../testdata/airdrop_stage_1_test_data.json | 10 - .../testdata/airdrop_stage_2_list.json | 13 - .../testdata/airdrop_stage_2_test_data.json | 11 - contracts/cw20-staking/.cargo/config | 6 - contracts/cw20-staking/Cargo.toml | 35 - contracts/cw20-staking/NOTICE | 14 - contracts/cw20-staking/README.md | 25 - contracts/cw20-staking/examples/schema.rs | 23 - contracts/cw20-staking/src/contract.rs | 965 ------ contracts/cw20-staking/src/error.rs | 69 - contracts/cw20-staking/src/lib.rs | 6 - contracts/cw20-staking/src/msg.rs | 130 - contracts/cw20-staking/src/state.rs | 43 - 70 files changed, 8938 deletions(-) delete mode 100644 contracts/cw20-atomic-swap/.cargo/config delete mode 100644 contracts/cw20-atomic-swap/Cargo.toml delete mode 100644 contracts/cw20-atomic-swap/NOTICE delete mode 100644 contracts/cw20-atomic-swap/README.md delete mode 100644 contracts/cw20-atomic-swap/examples/schema.rs delete mode 100644 contracts/cw20-atomic-swap/src/contract.rs delete mode 100644 contracts/cw20-atomic-swap/src/error.rs delete mode 100644 contracts/cw20-atomic-swap/src/lib.rs delete mode 100644 contracts/cw20-atomic-swap/src/msg.rs delete mode 100644 contracts/cw20-atomic-swap/src/state.rs delete mode 100644 contracts/cw20-bonding/.cargo/config delete mode 100644 contracts/cw20-bonding/Cargo.toml delete mode 100644 contracts/cw20-bonding/NOTICE delete mode 100644 contracts/cw20-bonding/README.md delete mode 100644 contracts/cw20-bonding/examples/schema.rs delete mode 100644 contracts/cw20-bonding/src/contract.rs delete mode 100644 contracts/cw20-bonding/src/curves.rs delete mode 100644 contracts/cw20-bonding/src/error.rs delete mode 100644 contracts/cw20-bonding/src/lib.rs delete mode 100644 contracts/cw20-bonding/src/msg.rs delete mode 100644 contracts/cw20-bonding/src/state.rs delete mode 100644 contracts/cw20-escrow/.cargo/config delete mode 100644 contracts/cw20-escrow/Cargo.toml delete mode 100644 contracts/cw20-escrow/NOTICE delete mode 100644 contracts/cw20-escrow/README.md delete mode 100644 contracts/cw20-escrow/examples/schema.rs delete mode 100644 contracts/cw20-escrow/src/contract.rs delete mode 100644 contracts/cw20-escrow/src/error.rs delete mode 100644 contracts/cw20-escrow/src/integration_test.rs delete mode 100644 contracts/cw20-escrow/src/lib.rs delete mode 100644 contracts/cw20-escrow/src/msg.rs delete mode 100644 contracts/cw20-escrow/src/state.rs delete mode 100644 contracts/cw20-merkle-airdrop/.cargo/config delete mode 100644 contracts/cw20-merkle-airdrop/Cargo.toml delete mode 100644 contracts/cw20-merkle-airdrop/NOTICE delete mode 100644 contracts/cw20-merkle-airdrop/README.md delete mode 100644 contracts/cw20-merkle-airdrop/examples/schema.rs delete mode 100644 contracts/cw20-merkle-airdrop/helpers/.eslintignore delete mode 100644 contracts/cw20-merkle-airdrop/helpers/.eslintrc delete mode 100644 contracts/cw20-merkle-airdrop/helpers/.gitignore delete mode 100644 contracts/cw20-merkle-airdrop/helpers/README.md delete mode 100755 contracts/cw20-merkle-airdrop/helpers/bin/run delete mode 100644 contracts/cw20-merkle-airdrop/helpers/bin/run.cmd delete mode 100644 contracts/cw20-merkle-airdrop/helpers/package.json delete mode 100644 contracts/cw20-merkle-airdrop/helpers/src/airdrop.ts delete mode 100644 contracts/cw20-merkle-airdrop/helpers/src/commands/generateProofs.ts delete mode 100644 contracts/cw20-merkle-airdrop/helpers/src/commands/generateRoot.ts delete mode 100644 contracts/cw20-merkle-airdrop/helpers/src/commands/verifyProofs.ts delete mode 100644 contracts/cw20-merkle-airdrop/helpers/src/index.ts delete mode 100644 contracts/cw20-merkle-airdrop/helpers/tsconfig.json delete mode 100644 contracts/cw20-merkle-airdrop/helpers/yarn.lock delete mode 100644 contracts/cw20-merkle-airdrop/src/contract.rs delete mode 100644 contracts/cw20-merkle-airdrop/src/error.rs delete mode 100644 contracts/cw20-merkle-airdrop/src/lib.rs delete mode 100644 contracts/cw20-merkle-airdrop/src/msg.rs delete mode 100644 contracts/cw20-merkle-airdrop/src/state.rs delete mode 100644 contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_list.json delete mode 100644 contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_test_data.json delete mode 100644 contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_list.json delete mode 100644 contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_test_data.json delete mode 100644 contracts/cw20-staking/.cargo/config delete mode 100644 contracts/cw20-staking/Cargo.toml delete mode 100644 contracts/cw20-staking/NOTICE delete mode 100644 contracts/cw20-staking/README.md delete mode 100644 contracts/cw20-staking/examples/schema.rs delete mode 100644 contracts/cw20-staking/src/contract.rs delete mode 100644 contracts/cw20-staking/src/error.rs delete mode 100644 contracts/cw20-staking/src/lib.rs delete mode 100644 contracts/cw20-staking/src/msg.rs delete mode 100644 contracts/cw20-staking/src/state.rs diff --git a/contracts/cw20-atomic-swap/.cargo/config b/contracts/cw20-atomic-swap/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/contracts/cw20-atomic-swap/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/contracts/cw20-atomic-swap/Cargo.toml b/contracts/cw20-atomic-swap/Cargo.toml deleted file mode 100644 index da1745131..000000000 --- a/contracts/cw20-atomic-swap/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "cw20-atomic-swap" -version = "0.11.1" -authors = ["Mauro Lacy "] -edition = "2018" -description = "Implementation of Atomic Swaps" -license = "Apache-2.0" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } -hex = "0.3.1" -sha2 = "0.8.0" - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-atomic-swap/NOTICE b/contracts/cw20-atomic-swap/NOTICE deleted file mode 100644 index c18423056..000000000 --- a/contracts/cw20-atomic-swap/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Atomic-Swap: A CosmWasm atomic swap contract that handles native tokens -Copyright (C) 2020 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-atomic-swap/README.md b/contracts/cw20-atomic-swap/README.md deleted file mode 100644 index 3bfa5cb16..000000000 --- a/contracts/cw20-atomic-swap/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Atomic Swaps - -This is a contract that allows users to execute atomic swaps. -It implements one side of an atomic swap. The other side can be realized -by an equivalent contract in the same blockchain or, typically, on a different blockchain. - -Each side of an atomic swap has a sender, a recipient, a hash, -and a timeout. It also has a unique id (for future calls to reference it). -The hash is a sha256-encoded 32-bytes long phrase. -The timeout can be either time-based (seconds since midnight, January 1, 1970), -or block height based. - -The basic function is, the sender chooses a 32-bytes long phrase as preimage, hashes it, -and then uses the hash to create a swap with funds. -Before the timeout, anybody that knows the preimage may decide to release the funds -to the original recipient. -After the timeout (and if no release has been executed), anyone can refund -the locked tokens to the original sender. -On the other side of the swap the process is similar, with sender and recipient exchanged. -The hash must be the same, so the first sender can claim the funds, revealing the preimage -and triggering the swap. - -See the [IOV atomic swap spec](https://github.com/iov-one/iov-core/blob/master/docs/atomic-swap-protocol-v1.md) -for details. - -## Token types - -Currently native tokens are supported; an upcoming version will support CW20 tokens. - -## Running this contract - -You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. - -You can run unit tests on this via: - -`cargo test` - -Once you are happy with the content, you can compile it to wasm via: - -``` -RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw20_atomic_swap.wasm . -ls -l cw20_atomic_swap.wasm -sha256sum cw20_atomic_swap.wasm -``` - -Or for a production-ready (optimized) build, run a build command in the -the repository root: https://github.com/CosmWasm/cw-plus#compiling. diff --git a/contracts/cw20-atomic-swap/examples/schema.rs b/contracts/cw20-atomic-swap/examples/schema.rs deleted file mode 100644 index f89e1bc25..000000000 --- a/contracts/cw20-atomic-swap/examples/schema.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20_atomic_swap::msg::DetailsResponse; -use cw20_atomic_swap::msg::ExecuteMsg; -use cw20_atomic_swap::msg::InstantiateMsg; -use cw20_atomic_swap::msg::ListResponse; -use cw20_atomic_swap::msg::QueryMsg; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(ListResponse), &out_dir); - export_schema(&schema_for!(DetailsResponse), &out_dir); -} diff --git a/contracts/cw20-atomic-swap/src/contract.rs b/contracts/cw20-atomic-swap/src/contract.rs deleted file mode 100644 index 6b24fa102..000000000 --- a/contracts/cw20-atomic-swap/src/contract.rs +++ /dev/null @@ -1,745 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - from_binary, to_binary, Addr, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, - StdResult, SubMsg, WasmMsg, -}; -use sha2::{Digest, Sha256}; - -use cw2::set_contract_version; -use cw20::{Balance, Cw20Coin, Cw20CoinVerified, Cw20ExecuteMsg, Cw20ReceiveMsg}; - -use crate::error::ContractError; -use crate::msg::{ - is_valid_name, BalanceHuman, CreateMsg, DetailsResponse, ExecuteMsg, InstantiateMsg, - ListResponse, QueryMsg, ReceiveMsg, -}; -use crate::state::{all_swap_ids, AtomicSwap, SWAPS}; -use cw_storage_plus::Bound; - -// Version info, for migration info -const CONTRACT_NAME: &str = "crates.io:cw20-atomic-swap"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: InstantiateMsg, -) -> StdResult { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // No setup - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Create(msg) => { - let sent_funds = info.funds.clone(); - execute_create(deps, env, info, msg, Balance::from(sent_funds)) - } - ExecuteMsg::Release { id, preimage } => execute_release(deps, env, id, preimage), - ExecuteMsg::Refund { id } => execute_refund(deps, env, id), - ExecuteMsg::Receive(msg) => execute_receive(deps, env, info, msg), - } -} - -pub fn execute_receive( - deps: DepsMut, - env: Env, - info: MessageInfo, - wrapper: Cw20ReceiveMsg, -) -> Result { - let msg: ReceiveMsg = from_binary(&wrapper.msg)?; - let token = Cw20CoinVerified { - address: info.sender, - amount: wrapper.amount, - }; - // we need to update the info... so the original sender is the one authorizing with these tokens - let orig_info = MessageInfo { - sender: deps.api.addr_validate(&wrapper.sender)?, - funds: info.funds, - }; - match msg { - ReceiveMsg::Create(create) => { - execute_create(deps, env, orig_info, create, Balance::Cw20(token)) - } - } -} - -pub fn execute_create( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: CreateMsg, - balance: Balance, -) -> Result { - if !is_valid_name(&msg.id) { - return Err(ContractError::InvalidId {}); - } - - // this ignores 0 value coins, must have one or more with positive balance - if balance.is_empty() { - return Err(ContractError::EmptyBalance {}); - } - - // Ensure this is 32 bytes hex-encoded, and decode - let hash = parse_hex_32(&msg.hash)?; - - if msg.expires.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - - let recipient = deps.api.addr_validate(&msg.recipient)?; - - let swap = AtomicSwap { - hash: Binary(hash), - recipient, - source: info.sender, - expires: msg.expires, - balance, - }; - - // Try to store it, fail if the id already exists (unmodifiable swaps) - SWAPS.update(deps.storage, &msg.id, |existing| match existing { - None => Ok(swap), - Some(_) => Err(ContractError::AlreadyExists {}), - })?; - - let res = Response::new() - .add_attribute("action", "create") - .add_attribute("id", msg.id) - .add_attribute("hash", msg.hash) - .add_attribute("recipient", msg.recipient); - Ok(res) -} - -pub fn execute_release( - deps: DepsMut, - env: Env, - id: String, - preimage: String, -) -> Result { - let swap = SWAPS.load(deps.storage, &id)?; - if swap.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - - let hash = Sha256::digest(&parse_hex_32(&preimage)?); - if hash.as_slice() != swap.hash.as_slice() { - return Err(ContractError::InvalidPreimage {}); - } - - // Delete the swap - SWAPS.remove(deps.storage, &id); - - // Send all tokens out - let msgs = send_tokens(&swap.recipient, swap.balance)?; - Ok(Response::new() - .add_submessages(msgs) - .add_attribute("action", "release") - .add_attribute("id", id) - .add_attribute("preimage", preimage) - .add_attribute("to", swap.recipient.to_string())) -} - -pub fn execute_refund(deps: DepsMut, env: Env, id: String) -> Result { - let swap = SWAPS.load(deps.storage, &id)?; - // Anyone can try to refund, as long as the contract is expired - if !swap.is_expired(&env.block) { - return Err(ContractError::NotExpired {}); - } - - // We delete the swap - SWAPS.remove(deps.storage, &id); - - let msgs = send_tokens(&swap.source, swap.balance)?; - Ok(Response::new() - .add_submessages(msgs) - .add_attribute("action", "refund") - .add_attribute("id", id) - .add_attribute("to", swap.source.to_string())) -} - -fn parse_hex_32(data: &str) -> Result, ContractError> { - match hex::decode(data) { - Ok(bin) => { - if bin.len() == 32 { - Ok(bin) - } else { - Err(ContractError::InvalidHash(bin.len() * 2)) - } - } - Err(e) => Err(ContractError::ParseError(e.to_string())), - } -} - -fn send_tokens(to: &Addr, amount: Balance) -> StdResult> { - if amount.is_empty() { - Ok(vec![]) - } else { - match amount { - Balance::Native(coins) => { - let msg = BankMsg::Send { - to_address: to.into(), - amount: coins.into_vec(), - }; - Ok(vec![SubMsg::new(msg)]) - } - Balance::Cw20(coin) => { - let msg = Cw20ExecuteMsg::Transfer { - recipient: to.into(), - amount: coin.amount, - }; - let exec = WasmMsg::Execute { - contract_addr: coin.address.into(), - msg: to_binary(&msg)?, - funds: vec![], - }; - Ok(vec![SubMsg::new(exec)]) - } - } - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::List { start_after, limit } => to_binary(&query_list(deps, start_after, limit)?), - QueryMsg::Details { id } => to_binary(&query_details(deps, id)?), - } -} - -fn query_details(deps: Deps, id: String) -> StdResult { - let swap = SWAPS.load(deps.storage, &id)?; - - // Convert balance to human balance - let balance_human = match swap.balance { - Balance::Native(coins) => BalanceHuman::Native(coins.into_vec()), - Balance::Cw20(coin) => BalanceHuman::Cw20(Cw20Coin { - address: coin.address.into(), - amount: coin.amount, - }), - }; - - let details = DetailsResponse { - id, - hash: hex::encode(swap.hash.as_slice()), - recipient: swap.recipient.into(), - source: swap.source.into(), - expires: swap.expires, - balance: balance_human, - }; - Ok(details) -} - -// Settings for pagination -const MAX_LIMIT: u32 = 30; -const DEFAULT_LIMIT: u32 = 10; - -fn query_list( - deps: Deps, - start_after: Option, - limit: Option, -) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(|s| Bound::exclusive(s.as_bytes())); - - Ok(ListResponse { - swaps: all_swap_ids(deps.storage, start, limit)?, - }) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coins, from_binary, StdError, Timestamp, Uint128}; - - use cw20::Expiration; - - use super::*; - - fn preimage() -> String { - hex::encode(b"This is a string, 32 bytes long.") - } - - fn custom_preimage(int: u16) -> String { - hex::encode(format!("This is a custom string: {:>7}", int)) - } - - fn real_hash() -> String { - hex::encode(&Sha256::digest(&hex::decode(preimage()).unwrap())) - } - - fn custom_hash(int: u16) -> String { - hex::encode(&Sha256::digest(&hex::decode(custom_preimage(int)).unwrap())) - } - - fn mock_env_height(height: u64) -> Env { - let mut env = mock_env(); - env.block.height = height; - env - } - - #[test] - fn test_instantiate() { - let mut deps = mock_dependencies(); - - // Instantiate an empty contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info("anyone", &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - } - - #[test] - fn test_create() { - let mut deps = mock_dependencies(); - - let info = mock_info("anyone", &[]); - instantiate(deps.as_mut(), mock_env(), info, InstantiateMsg {}).unwrap(); - - let sender = String::from("sender0001"); - let balance = coins(100, "tokens"); - - // Cannot create, invalid ids - let info = mock_info(&sender, &balance); - for id in &["sh", "atomic_swap_id_too_long"] { - let create = CreateMsg { - id: id.to_string(), - hash: real_hash(), - recipient: String::from("rcpt0001"), - expires: Expiration::AtHeight(123456), - }; - let err = execute( - deps.as_mut(), - mock_env(), - info.clone(), - ExecuteMsg::Create(create.clone()), - ) - .unwrap_err(); - assert_eq!(err, ContractError::InvalidId {}); - } - - // Cannot create, no funds - let info = mock_info(&sender, &[]); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap_err(); - assert_eq!(err, ContractError::EmptyBalance {}); - - // Cannot create, expired - let info = mock_info(&sender, &balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtTime(Timestamp::from_seconds(1)), - }; - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap_err(); - assert_eq!(err, ContractError::Expired {}); - - // Cannot create, invalid hash - let info = mock_info(&sender, &balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: "bu115h17".to_string(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap_err(); - assert_eq!( - err, - ContractError::ParseError("Invalid character \'u\' at position 1".into()) - ); - - // Can create, all valid - let info = mock_info(&sender, &balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - let res = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // Cannot re-create (modify), already existing - let new_balance = coins(1, "tokens"); - let info = mock_info(&sender, &new_balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap_err(); - assert_eq!(err, ContractError::AlreadyExists {}); - } - - #[test] - fn test_release() { - let mut deps = mock_dependencies(); - - let info = mock_info("anyone", &[]); - instantiate(deps.as_mut(), mock_env(), info, InstantiateMsg {}).unwrap(); - - let sender = String::from("sender0001"); - let balance = coins(1000, "tokens"); - - let info = mock_info(&sender, &balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - execute( - deps.as_mut(), - mock_env(), - info, - ExecuteMsg::Create(create.clone()), - ) - .unwrap(); - - // Anyone can attempt release - let info = mock_info("somebody", &[]); - - // Cannot release, wrong id - let release = ExecuteMsg::Release { - id: "swap0002".to_string(), - preimage: preimage(), - }; - let err = execute(deps.as_mut(), mock_env(), info.clone(), release).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - - // Cannot release, invalid hash - let release = ExecuteMsg::Release { - id: "swap0001".to_string(), - preimage: "bu115h17".to_string(), - }; - let err = execute(deps.as_mut(), mock_env(), info.clone(), release).unwrap_err(); - assert_eq!( - err, - ContractError::ParseError("Invalid character \'u\' at position 1".to_string()) - ); - - // Cannot release, wrong hash - let release = ExecuteMsg::Release { - id: "swap0001".to_string(), - preimage: hex::encode(b"This is 32 bytes, but incorrect."), - }; - let err = execute(deps.as_mut(), mock_env(), info, release).unwrap_err(); - assert!(matches!(err, ContractError::InvalidPreimage {})); - - // Cannot release, expired - let env = mock_env_height(123457); - let info = mock_info("somebody", &[]); - let release = ExecuteMsg::Release { - id: "swap0001".to_string(), - preimage: preimage(), - }; - let err = execute(deps.as_mut(), env, info, release).unwrap_err(); - assert!(matches!(err, ContractError::Expired)); - - // Can release, valid id, valid hash, and not expired - let info = mock_info("somebody", &[]); - let release = ExecuteMsg::Release { - id: "swap0001".to_string(), - preimage: preimage(), - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), release.clone()).unwrap(); - assert_eq!(("action", "release"), res.attributes[0]); - assert_eq!(1, res.messages.len()); - assert_eq!( - res.messages[0], - SubMsg::new(BankMsg::Send { - to_address: create.recipient, - amount: balance, - }) - ); - - // Cannot release again - let err = execute(deps.as_mut(), mock_env(), info, release).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - } - - #[test] - fn test_refund() { - let mut deps = mock_dependencies(); - - let info = mock_info("anyone", &[]); - instantiate(deps.as_mut(), mock_env(), info, InstantiateMsg {}).unwrap(); - - let sender = String::from("sender0001"); - let balance = coins(1000, "tokens"); - - let info = mock_info(&sender, &balance); - let create = CreateMsg { - id: "swap0001".to_string(), - hash: real_hash(), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap(); - - // Anyone can attempt refund - let info = mock_info("somebody", &[]); - - // Cannot refund, wrong id - let refund = ExecuteMsg::Refund { - id: "swap0002".to_string(), - }; - let err = execute(deps.as_mut(), mock_env(), info.clone(), refund).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - - // Cannot refund, not expired yet - let refund = ExecuteMsg::Refund { - id: "swap0001".to_string(), - }; - let err = execute(deps.as_mut(), mock_env(), info, refund).unwrap_err(); - assert!(matches!(err, ContractError::NotExpired { .. })); - - // Anyone can refund, if already expired - let env = mock_env_height(123457); - let info = mock_info("somebody", &[]); - let refund = ExecuteMsg::Refund { - id: "swap0001".to_string(), - }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), refund.clone()).unwrap(); - assert_eq!(("action", "refund"), res.attributes[0]); - assert_eq!(1, res.messages.len()); - assert_eq!( - res.messages[0], - SubMsg::new(BankMsg::Send { - to_address: sender, - amount: balance, - }) - ); - - // Cannot refund again - let err = execute(deps.as_mut(), env, info, refund).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - } - - #[test] - fn test_query() { - let mut deps = mock_dependencies(); - - let info = mock_info("anyone", &[]); - instantiate(deps.as_mut(), mock_env(), info, InstantiateMsg {}).unwrap(); - - let sender1 = String::from("sender0001"); - let sender2 = String::from("sender0002"); - // Same balance for simplicity - let balance = coins(1000, "tokens"); - - // Create a couple swaps (same hash for simplicity) - let info = mock_info(&sender1, &balance); - let create1 = CreateMsg { - id: "swap0001".to_string(), - hash: custom_hash(1), - recipient: "rcpt0001".into(), - expires: Expiration::AtHeight(123456), - }; - execute( - deps.as_mut(), - mock_env(), - info, - ExecuteMsg::Create(create1.clone()), - ) - .unwrap(); - - let info = mock_info(&sender2, &balance); - let create2 = CreateMsg { - id: "swap0002".to_string(), - hash: custom_hash(2), - recipient: "rcpt0002".into(), - expires: Expiration::AtTime(Timestamp::from_seconds(2_000_000_000)), - }; - execute( - deps.as_mut(), - mock_env(), - info, - ExecuteMsg::Create(create2.clone()), - ) - .unwrap(); - - // Get the list of ids - let query_msg = QueryMsg::List { - start_after: None, - limit: None, - }; - let ids: ListResponse = - from_binary(&query(deps.as_ref(), mock_env(), query_msg).unwrap()).unwrap(); - assert_eq!(2, ids.swaps.len()); - assert_eq!(vec!["swap0001", "swap0002"], ids.swaps); - - // Get the details for the first swap id - let query_msg = QueryMsg::Details { - id: ids.swaps[0].clone(), - }; - let res: DetailsResponse = - from_binary(&query(deps.as_ref(), mock_env(), query_msg).unwrap()).unwrap(); - assert_eq!( - res, - DetailsResponse { - id: create1.id, - hash: create1.hash, - recipient: create1.recipient, - source: sender1, - expires: create1.expires, - balance: BalanceHuman::Native(balance.clone()), - } - ); - - // Get the details for the second swap id - let query_msg = QueryMsg::Details { - id: ids.swaps[1].clone(), - }; - let res: DetailsResponse = - from_binary(&query(deps.as_ref(), mock_env(), query_msg).unwrap()).unwrap(); - assert_eq!( - res, - DetailsResponse { - id: create2.id, - hash: create2.hash, - recipient: create2.recipient, - source: sender2, - expires: create2.expires, - balance: BalanceHuman::Native(balance), - } - ); - } - - #[test] - fn test_native_cw20_swap() { - let mut deps = mock_dependencies(); - - // Create the contract - let info = mock_info("anyone", &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, InstantiateMsg {}).unwrap(); - assert_eq!(0, res.messages.len()); - - // Native side (offer) - let native_sender = String::from("A_on_X"); - let native_rcpt = String::from("B_on_X"); - let native_coins = coins(1000, "tokens_native"); - - // Create the Native swap offer - let native_swap_id = "native_swap".to_string(); - let create = CreateMsg { - id: native_swap_id.clone(), - hash: real_hash(), - recipient: native_rcpt.clone(), - expires: Expiration::AtHeight(123456), - }; - let info = mock_info(&native_sender, &native_coins); - let res = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Create(create)).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // Cw20 side (counter offer (1:1000)) - let cw20_sender = String::from("B_on_Y"); - let cw20_rcpt = String::from("A_on_Y"); - let cw20_coin = Cw20Coin { - address: String::from("my_cw20_token"), - amount: Uint128::new(1), - }; - - // Create the Cw20 side swap counter offer - let cw20_swap_id = "cw20_swap".to_string(); - let create = CreateMsg { - id: cw20_swap_id.clone(), - hash: real_hash(), - recipient: cw20_rcpt.clone(), - expires: Expiration::AtHeight(123000), - }; - let receive = Cw20ReceiveMsg { - sender: cw20_sender, - amount: cw20_coin.amount, - msg: to_binary(&ExecuteMsg::Create(create)).unwrap(), - }; - let token_contract = cw20_coin.address; - let info = mock_info(&token_contract, &[]); - let res = execute( - deps.as_mut(), - mock_env(), - info, - ExecuteMsg::Receive(receive), - ) - .unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // Somebody (typically, A) releases the swap side on the Cw20 (Y) blockchain, - // using her knowledge of the preimage - let info = mock_info("somebody", &[]); - let res = execute( - deps.as_mut(), - mock_env(), - info, - ExecuteMsg::Release { - id: cw20_swap_id.clone(), - preimage: preimage(), - }, - ) - .unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!(("action", "release"), res.attributes[0]); - assert_eq!(("id", cw20_swap_id), res.attributes[1]); - - // Verify the resulting Cw20 transfer message - let send_msg = Cw20ExecuteMsg::Transfer { - recipient: cw20_rcpt, - amount: cw20_coin.amount, - }; - assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::Execute { - contract_addr: token_contract, - msg: to_binary(&send_msg).unwrap(), - funds: vec![], - }) - ); - - // Now somebody (typically, B) releases the original offer on the Native (X) blockchain, - // using the (now public) preimage - let info = mock_info("other_somebody", &[]); - - // First, let's obtain the preimage from the logs of the release() transaction on Y - let preimage_attr = &res.attributes[2]; - assert_eq!("preimage", preimage_attr.key); - let preimage = preimage_attr.value.clone(); - - let release = ExecuteMsg::Release { - id: native_swap_id.clone(), - preimage, - }; - let res = execute(deps.as_mut(), mock_env(), info, release).unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!(("action", "release"), res.attributes[0]); - assert_eq!(("id", native_swap_id), res.attributes[1]); - - // Verify the resulting Native send message - assert_eq!( - res.messages[0], - SubMsg::new(BankMsg::Send { - to_address: native_rcpt, - amount: native_coins, - }) - ); - } -} diff --git a/contracts/cw20-atomic-swap/src/error.rs b/contracts/cw20-atomic-swap/src/error.rs deleted file mode 100644 index 29d725666..000000000 --- a/contracts/cw20-atomic-swap/src/error.rs +++ /dev/null @@ -1,32 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Hash parse error: {0}")] - ParseError(String), - - #[error("Invalid atomic swap id")] - InvalidId {}, - - #[error("Invalid preimage")] - InvalidPreimage {}, - - #[error("Invalid hash ({0} chars): must be 64 characters")] - InvalidHash(usize), - - #[error("Send some coins to create an atomic swap")] - EmptyBalance {}, - - #[error("Atomic swap not yet expired")] - NotExpired, - - #[error("Expired atomic swap")] - Expired, - - #[error("Atomic swap already exists")] - AlreadyExists, -} diff --git a/contracts/cw20-atomic-swap/src/lib.rs b/contracts/cw20-atomic-swap/src/lib.rs deleted file mode 100644 index dfedc9dc6..000000000 --- a/contracts/cw20-atomic-swap/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod contract; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/contracts/cw20-atomic-swap/src/msg.rs b/contracts/cw20-atomic-swap/src/msg.rs deleted file mode 100644 index ed1f583b0..000000000 --- a/contracts/cw20-atomic-swap/src/msg.rs +++ /dev/null @@ -1,96 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Coin; -use cw20::{Cw20Coin, Cw20ReceiveMsg, Expiration}; - -#[derive(Serialize, Deserialize, JsonSchema)] -pub struct InstantiateMsg {} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - Create(CreateMsg), - /// Release sends all tokens to the recipient. - Release { - id: String, - /// This is the preimage, must be exactly 32 bytes in hex (64 chars) - /// to release: sha256(from_hex(preimage)) == from_hex(hash) - preimage: String, - }, - /// Refund returns all remaining tokens to the original sender, - Refund { - id: String, - }, - /// This accepts a properly-encoded ReceiveMsg from a cw20 contract - Receive(Cw20ReceiveMsg), -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ReceiveMsg { - Create(CreateMsg), -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct CreateMsg { - /// id is a human-readable name for the swap to use later. - /// 3-20 bytes of utf-8 text - pub id: String, - /// This is hex-encoded sha-256 hash of the preimage (must be 32*2 = 64 chars) - pub hash: String, - /// If approved, funds go to the recipient - pub recipient: String, - /// You can set expiration at time or at block height the contract is valid at. - /// After the contract is expired, it can be returned to the original funder. - pub expires: Expiration, -} - -pub fn is_valid_name(name: &str) -> bool { - let bytes = name.as_bytes(); - if bytes.len() < 3 || bytes.len() > 20 { - return false; - } - true -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Show all open swaps. Return type is ListResponse. - List { - start_after: Option, - limit: Option, - }, - /// Returns the details of the named swap, error if not created. - /// Return type: DetailsResponse. - Details { id: String }, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct ListResponse { - /// List all open swap ids - pub swaps: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct DetailsResponse { - /// Id of this swap - pub id: String, - /// This is hex-encoded sha-256 hash of the preimage (must be 32*2 = 64 chars) - pub hash: String, - /// If released, funds go to the recipient - pub recipient: String, - /// If refunded, funds go to the source - pub source: String, - /// Once a swap is expired, it can be returned to the original source (via "refund"). - pub expires: Expiration, - /// Balance in native tokens or cw20 token, with human-readable address - pub balance: BalanceHuman, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub enum BalanceHuman { - Native(Vec), - Cw20(Cw20Coin), -} diff --git a/contracts/cw20-atomic-swap/src/state.rs b/contracts/cw20-atomic-swap/src/state.rs deleted file mode 100644 index de231bd74..000000000 --- a/contracts/cw20-atomic-swap/src/state.rs +++ /dev/null @@ -1,78 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Addr, Binary, BlockInfo, Order, StdResult, Storage}; -use cw_storage_plus::{Bound, Map}; - -use cw20::{Balance, Expiration}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct AtomicSwap { - /// This is the sha-256 hash of the preimage - pub hash: Binary, - pub recipient: Addr, - pub source: Addr, - pub expires: Expiration, - /// Balance in native tokens, or cw20 token - pub balance: Balance, -} - -impl AtomicSwap { - pub fn is_expired(&self, block: &BlockInfo) -> bool { - self.expires.is_expired(block) - } -} - -pub const SWAPS: Map<&str, AtomicSwap> = Map::new("atomic_swap"); - -/// This returns the list of ids for all active swaps -pub fn all_swap_ids( - storage: &dyn Storage, - start: Option, - limit: usize, -) -> StdResult> { - SWAPS - .keys(storage, start, None, Order::Ascending) - .take(limit) - .collect() -} - -#[cfg(test)] -mod tests { - use super::*; - - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::Binary; - - #[test] - fn test_no_swap_ids() { - let storage = MockStorage::new(); - let ids = all_swap_ids(&storage, None, 10).unwrap(); - assert_eq!(0, ids.len()); - } - - fn dummy_swap() -> AtomicSwap { - AtomicSwap { - recipient: Addr::unchecked("recip"), - source: Addr::unchecked("source"), - expires: Default::default(), - hash: Binary("hash".into()), - balance: Default::default(), - } - } - - #[test] - fn test_all_swap_ids() { - let mut storage = MockStorage::new(); - SWAPS.save(&mut storage, "lazy", &dummy_swap()).unwrap(); - SWAPS.save(&mut storage, "assign", &dummy_swap()).unwrap(); - SWAPS.save(&mut storage, "zen", &dummy_swap()).unwrap(); - - let ids = all_swap_ids(&storage, None, 10).unwrap(); - assert_eq!(3, ids.len()); - assert_eq!( - vec!["assign".to_string(), "lazy".to_string(), "zen".to_string()], - ids - ) - } -} diff --git a/contracts/cw20-bonding/.cargo/config b/contracts/cw20-bonding/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/contracts/cw20-bonding/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/contracts/cw20-bonding/Cargo.toml b/contracts/cw20-bonding/Cargo.toml deleted file mode 100644 index 2c4508a70..000000000 --- a/contracts/cw20-bonding/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "cw20-bonding" -version = "0.11.1" -authors = ["Ethan Frey "] -edition = "2018" -description = "Implement basic bonding curve to issue cw20 tokens" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.11.1", features = ["library"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } -cosmwasm-std = { version = "1.0.0-beta3", default-features = false, features = ["staking"] } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } -rust_decimal = { version = "1.14.3" } -integer-sqrt = { version = "0.1.5" } -integer-cbrt = { version = "0.1.2" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-bonding/NOTICE b/contracts/cw20-bonding/NOTICE deleted file mode 100644 index a3cf0c354..000000000 --- a/contracts/cw20-bonding/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-Bonding: Bonding Curve to release CW20 token -Copyright 2020 Ethan Frey - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-bonding/README.md b/contracts/cw20-bonding/README.md deleted file mode 100644 index c16ba96bb..000000000 --- a/contracts/cw20-bonding/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# CW20 Bonding curve - -This builds on the [Basic CW20 interface](../../packages/cw20/README.md) -as implemented in [`cw20-base`](../cw20-base/README.md). - -This serves three purposes: - -* A usable and extensible contract for arbitrary bonding curves -* A demonstration of how to extend `cw20-base` to add extra functionality -* A demonstration of the [Receiver interface]([Basic CW20 interface](../../packages/cw20/README.md#receiver)) - -## Design - -There are two variants - accepting native tokens and accepting cw20 tokens -as the *reserve* token (this is the token that is input to the bonding curve). - -Minting: When the input is sent to the contract (either via `ExecuteMsg::Buy{}` -with native tokens, or via `ExecuteMsg::Receive{}` with cw20 tokens), -those tokens remain on the contract and it issues it's own token to the -sender's account (known as *supply* token). - -Burning: We override the burn function to not only burn the requested tokens, -but also release a proper number of the input tokens to the account that burnt -the custom token - -Curves: `handle` specifies a bonding function, which is sent to parameterize -`handle_fn` (which does all the work). The curve is set when compiling -the contract. In fact many contracts can just wrap `cw20-bonding` and -specify the custom curve parameter. - -Read more about [bonding curve math here](https://yos.io/2018/11/10/bonding-curves/) - -Note: the first version only accepts native tokens as the - -### Math - -Given a price curve `f(x)` = price of the `x`th token, we want to figure out -how to buy into and sell from the bonding curve. In fact we can look at -the total supply issued. let `F(x)` be the integral of `f(x)`. We have issued -`x` tokens for `F(x)` sent to the contract. Or, in reverse, if we send -`x` tokens to the contract, it will mint `F^-1(x)` tokens. - -From this we can create some formulas. Assume we currently have issued `S` -tokens in exchange for `N = F(S)` input tokens. If someone sends us `x` tokens, -how much will we issue? - -`F^-1(N+x) - F^-1(N)` = `F^-1(N+x) - S` - -And if we sell `x` tokens, how much we will get out: - -`F(S) - F(S-x)` = `N - F(S-x)` - -Just one calculation each side. To be safe, make sure to round down and -always check against `F(S)` when using `F^-1(S)` to estimate how much -should be issued. This will also safely give us how many tokens to return. - -There is built in support for safely [raising i128 to an integer power](https://doc.rust-lang.org/std/primitive.i128.html#method.checked_pow). -There is also a crate to [provide nth-root of for all integers](https://docs.rs/num-integer/0.1.43/num_integer/trait.Roots.html). -With these two, we can handle most math except for logs/exponents. - -Compare this to [writing it all in solidity](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7b7ff729b82ea73ea168e495d9c94cb901ae95ce/contracts/math/Power.sol) - -Examples: - -Price Constant: `f(x) = k` and `F(x) = kx` and `F^-1(x) = x/k` - -Price Linear: `f(x) = kx` and `F(x) = kx^2/2` and `F^-1(x) = (2x/k)^(0.5)` - -Price Square Root: `f(x) = x^0.5` and `F(x) = x^1.5/1.5` and `F^-1(x) = (1.5*x)^(2/3)` - -We will only implement these curves to start with, and leave it to others to import this with more complex curves, -such as logarithms. \ No newline at end of file diff --git a/contracts/cw20-bonding/examples/schema.rs b/contracts/cw20-bonding/examples/schema.rs deleted file mode 100644 index dcc0805bc..000000000 --- a/contracts/cw20-bonding/examples/schema.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20::{AllowanceResponse, BalanceResponse, TokenInfoResponse}; -use cw20_bonding::msg::{CurveInfoResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(AllowanceResponse), &out_dir); - export_schema(&schema_for!(BalanceResponse), &out_dir); - export_schema(&schema_for!(CurveInfoResponse), &out_dir); - export_schema(&schema_for!(TokenInfoResponse), &out_dir); -} diff --git a/contracts/cw20-bonding/src/contract.rs b/contracts/cw20-bonding/src/contract.rs deleted file mode 100644 index a3a33aed2..000000000 --- a/contracts/cw20-bonding/src/contract.rs +++ /dev/null @@ -1,636 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - attr, coins, to_binary, Addr, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, - StdError, StdResult, Uint128, -}; - -use cw2::set_contract_version; -use cw20_base::allowances::{ - deduct_allowance, execute_decrease_allowance, execute_increase_allowance, execute_send_from, - execute_transfer_from, query_allowance, -}; -use cw20_base::contract::{ - execute_burn, execute_mint, execute_send, execute_transfer, query_balance, query_token_info, -}; -use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO}; - -use crate::curves::DecimalPlaces; -use crate::error::ContractError; -use crate::msg::{CurveFn, CurveInfoResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{CurveState, CURVE_STATE, CURVE_TYPE}; -use cw_utils::{must_pay, nonpayable}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw20-bonding"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - nonpayable(&info)?; - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // store token info using cw20-base format - let data = TokenInfo { - name: msg.name, - symbol: msg.symbol, - decimals: msg.decimals, - total_supply: Uint128::zero(), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address, - cap: None, - }), - }; - TOKEN_INFO.save(deps.storage, &data)?; - - let places = DecimalPlaces::new(msg.decimals, msg.reserve_decimals); - let supply = CurveState::new(msg.reserve_denom, places); - CURVE_STATE.save(deps.storage, &supply)?; - - CURVE_TYPE.save(deps.storage, &msg.curve_type)?; - - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - // default implementation stores curve info as enum, you can do something else in a derived - // contract and just pass in your custom curve to do_execute - let curve_type = CURVE_TYPE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - do_execute(deps, env, info, msg, curve_fn) -} - -/// We pull out logic here, so we can import this from another contract and set a different Curve. -/// This contacts sets a curve with an enum in InstantiateMsg and stored in state, but you may want -/// to use custom math not included - make this easily reusable -pub fn do_execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, - curve_fn: CurveFn, -) -> Result { - match msg { - ExecuteMsg::Buy {} => execute_buy(deps, env, info, curve_fn), - - // we override these from cw20 - ExecuteMsg::Burn { amount } => Ok(execute_sell(deps, env, info, curve_fn, amount)?), - ExecuteMsg::BurnFrom { owner, amount } => { - Ok(execute_sell_from(deps, env, info, curve_fn, owner, amount)?) - } - - // these all come from cw20-base to implement the cw20 standard - ExecuteMsg::Transfer { recipient, amount } => { - Ok(execute_transfer(deps, env, info, recipient, amount)?) - } - ExecuteMsg::Send { - contract, - amount, - msg, - } => Ok(execute_send(deps, env, info, contract, amount, msg)?), - ExecuteMsg::IncreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_increase_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::DecreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_decrease_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::TransferFrom { - owner, - recipient, - amount, - } => Ok(execute_transfer_from( - deps, env, info, owner, recipient, amount, - )?), - ExecuteMsg::SendFrom { - owner, - contract, - amount, - msg, - } => Ok(execute_send_from( - deps, env, info, owner, contract, amount, msg, - )?), - } -} - -pub fn execute_buy( - deps: DepsMut, - env: Env, - info: MessageInfo, - curve_fn: CurveFn, -) -> Result { - let mut state = CURVE_STATE.load(deps.storage)?; - - let payment = must_pay(&info, &state.reserve_denom)?; - - // calculate how many tokens can be purchased with this and mint them - let curve = curve_fn(state.decimals); - state.reserve += payment; - let new_supply = curve.supply(state.reserve); - let minted = new_supply - .checked_sub(state.supply) - .map_err(StdError::overflow)?; - state.supply = new_supply; - CURVE_STATE.save(deps.storage, &state)?; - - // call into cw20-base to mint the token, call as self as no one else is allowed - let sub_info = MessageInfo { - sender: env.contract.address.clone(), - funds: vec![], - }; - execute_mint(deps, env, sub_info, info.sender.to_string(), minted)?; - - // bond them to the validator - let res = Response::new() - .add_attribute("action", "buy") - .add_attribute("from", info.sender) - .add_attribute("reserve", payment) - .add_attribute("supply", minted); - Ok(res) -} - -pub fn execute_sell( - deps: DepsMut, - env: Env, - info: MessageInfo, - curve_fn: CurveFn, - amount: Uint128, -) -> Result { - nonpayable(&info)?; - let receiver = info.sender.clone(); - // do all the work - let mut res = do_sell(deps, env, info, curve_fn, receiver, amount)?; - - // add our custom attributes - res.attributes.push(attr("action", "burn")); - Ok(res) -} - -pub fn execute_sell_from( - deps: DepsMut, - env: Env, - info: MessageInfo, - curve_fn: CurveFn, - owner: String, - amount: Uint128, -) -> Result { - nonpayable(&info)?; - let owner_addr = deps.api.addr_validate(&owner)?; - let spender_addr = info.sender.clone(); - - // deduct allowance before doing anything else have enough allowance - deduct_allowance(deps.storage, &owner_addr, &spender_addr, &env.block, amount)?; - - // do all the work in do_sell - let receiver_addr = info.sender; - let owner_info = MessageInfo { - sender: owner_addr, - funds: info.funds, - }; - let mut res = do_sell( - deps, - env, - owner_info, - curve_fn, - receiver_addr.clone(), - amount, - )?; - - // add our custom attributes - res.attributes.push(attr("action", "burn_from")); - res.attributes.push(attr("by", receiver_addr)); - Ok(res) -} - -fn do_sell( - mut deps: DepsMut, - env: Env, - // info.sender is the one burning tokens - info: MessageInfo, - curve_fn: CurveFn, - // receiver is the one who gains (same for execute_sell, diff for execute_sell_from) - receiver: Addr, - amount: Uint128, -) -> Result { - // burn from the caller, this ensures there are tokens to cover this - execute_burn(deps.branch(), env, info.clone(), amount)?; - - // calculate how many tokens can be purchased with this and mint them - let mut state = CURVE_STATE.load(deps.storage)?; - let curve = curve_fn(state.decimals); - state.supply = state - .supply - .checked_sub(amount) - .map_err(StdError::overflow)?; - let new_reserve = curve.reserve(state.supply); - let released = state - .reserve - .checked_sub(new_reserve) - .map_err(StdError::overflow)?; - state.reserve = new_reserve; - CURVE_STATE.save(deps.storage, &state)?; - - // now send the tokens to the sender (TODO: for sell_from we do something else, right???) - let msg = BankMsg::Send { - to_address: receiver.to_string(), - amount: coins(released.u128(), state.reserve_denom), - }; - let res = Response::new() - .add_message(msg) - .add_attribute("from", info.sender) - .add_attribute("supply", amount) - .add_attribute("reserve", released); - Ok(res) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - // default implementation stores curve info as enum, you can do something else in a derived - // contract and just pass in your custom curve to do_execute - let curve_type = CURVE_TYPE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - do_query(deps, env, msg, curve_fn) -} - -/// We pull out logic here, so we can import this from another contract and set a different Curve. -/// This contacts sets a curve with an enum in InstantitateMsg and stored in state, but you may want -/// to use custom math not included - make this easily reusable -pub fn do_query(deps: Deps, _env: Env, msg: QueryMsg, curve_fn: CurveFn) -> StdResult { - match msg { - // custom queries - QueryMsg::CurveInfo {} => to_binary(&query_curve_info(deps, curve_fn)?), - // inherited from cw20-base - QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?), - QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?), - QueryMsg::Allowance { owner, spender } => { - to_binary(&query_allowance(deps, owner, spender)?) - } - } -} - -pub fn query_curve_info(deps: Deps, curve_fn: CurveFn) -> StdResult { - let CurveState { - reserve, - supply, - reserve_denom, - decimals, - } = CURVE_STATE.load(deps.storage)?; - - // This we can get from the local digits stored in instantiate - let curve = curve_fn(decimals); - let spot_price = curve.spot_price(supply); - - Ok(CurveInfoResponse { - reserve, - supply, - spot_price, - reserve_denom, - }) -} - -// this is poor mans "skip" flag -#[cfg(test)] -mod tests { - use super::*; - use crate::msg::CurveType; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coin, Decimal, OverflowError, OverflowOperation, StdError, SubMsg}; - use cw_utils::PaymentError; - - const DENOM: &str = "satoshi"; - const CREATOR: &str = "creator"; - const INVESTOR: &str = "investor"; - const BUYER: &str = "buyer"; - - fn default_instantiate( - decimals: u8, - reserve_decimals: u8, - curve_type: CurveType, - ) -> InstantiateMsg { - InstantiateMsg { - name: "Bonded".to_string(), - symbol: "EPOXY".to_string(), - decimals, - reserve_denom: DENOM.to_string(), - reserve_decimals, - curve_type, - } - } - - fn get_balance>(deps: Deps, addr: U) -> Uint128 { - query_balance(deps, addr.into()).unwrap().balance - } - - fn setup_test(deps: DepsMut, decimals: u8, reserve_decimals: u8, curve_type: CurveType) { - // this matches `linear_curve` test case from curves.rs - let creator = String::from(CREATOR); - let msg = default_instantiate(decimals, reserve_decimals, curve_type); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps, mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - - // this matches `linear_curve` test case from curves.rs - let creator = String::from("creator"); - let curve_type = CurveType::SquareRoot { - slope: Uint128::new(1), - scale: 1, - }; - let msg = default_instantiate(2, 8, curve_type.clone()); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, msg.clone()).unwrap(); - assert_eq!(0, res.messages.len()); - - // token info is proper - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(&token.name, &msg.name); - assert_eq!(&token.symbol, &msg.symbol); - assert_eq!(token.decimals, 2); - assert_eq!(token.total_supply, Uint128::zero()); - - // curve state is sensible - let state = query_curve_info(deps.as_ref(), curve_type.to_curve_fn()).unwrap(); - assert_eq!(state.reserve, Uint128::zero()); - assert_eq!(state.supply, Uint128::zero()); - assert_eq!(state.reserve_denom.as_str(), DENOM); - // spot price 0 as supply is 0 - assert_eq!(state.spot_price, Decimal::zero()); - - // curve type is stored properly - let curve = CURVE_TYPE.load(&deps.storage).unwrap(); - assert_eq!(curve_type, curve); - - // no balance - assert_eq!(get_balance(deps.as_ref(), &creator), Uint128::zero()); - } - - #[test] - fn buy_issues_tokens() { - let mut deps = mock_dependencies(); - let curve_type = CurveType::Linear { - slope: Uint128::new(1), - scale: 1, - }; - setup_test(deps.as_mut(), 2, 8, curve_type.clone()); - - // succeeds with proper token (5 BTC = 5*10^8 satoshi) - let info = mock_info(INVESTOR, &coins(500_000_000, DENOM)); - let buy = ExecuteMsg::Buy {}; - execute(deps.as_mut(), mock_env(), info, buy.clone()).unwrap(); - - // bob got 1000 EPOXY (10.00) - assert_eq!(get_balance(deps.as_ref(), INVESTOR), Uint128::new(1000)); - assert_eq!(get_balance(deps.as_ref(), BUYER), Uint128::zero()); - - // send them all to buyer - let info = mock_info(INVESTOR, &[]); - let send = ExecuteMsg::Transfer { - recipient: BUYER.into(), - amount: Uint128::new(1000), - }; - execute(deps.as_mut(), mock_env(), info, send).unwrap(); - - // ensure balances updated - assert_eq!(get_balance(deps.as_ref(), INVESTOR), Uint128::zero()); - assert_eq!(get_balance(deps.as_ref(), BUYER), Uint128::new(1000)); - - // second stake needs more to get next 1000 EPOXY - let info = mock_info(INVESTOR, &coins(1_500_000_000, DENOM)); - execute(deps.as_mut(), mock_env(), info, buy).unwrap(); - - // ensure balances updated - assert_eq!(get_balance(deps.as_ref(), INVESTOR), Uint128::new(1000)); - assert_eq!(get_balance(deps.as_ref(), BUYER), Uint128::new(1000)); - - // check curve info updated - let curve = query_curve_info(deps.as_ref(), curve_type.to_curve_fn()).unwrap(); - assert_eq!(curve.reserve, Uint128::new(2_000_000_000)); - assert_eq!(curve.supply, Uint128::new(2000)); - assert_eq!(curve.spot_price, Decimal::percent(200)); - - // check token info updated - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(token.decimals, 2); - assert_eq!(token.total_supply, Uint128::new(2000)); - } - - #[test] - fn bonding_fails_with_wrong_denom() { - let mut deps = mock_dependencies(); - let curve_type = CurveType::Linear { - slope: Uint128::new(1), - scale: 1, - }; - setup_test(deps.as_mut(), 2, 8, curve_type); - - // fails when no tokens sent - let info = mock_info(INVESTOR, &[]); - let buy = ExecuteMsg::Buy {}; - let err = execute(deps.as_mut(), mock_env(), info, buy.clone()).unwrap_err(); - assert_eq!(err, PaymentError::NoFunds {}.into()); - - // fails when wrong tokens sent - let info = mock_info(INVESTOR, &coins(1234567, "wei")); - let err = execute(deps.as_mut(), mock_env(), info, buy.clone()).unwrap_err(); - assert_eq!(err, PaymentError::MissingDenom(DENOM.into()).into()); - - // fails when too many tokens sent - let info = mock_info(INVESTOR, &[coin(3400022, DENOM), coin(1234567, "wei")]); - let err = execute(deps.as_mut(), mock_env(), info, buy).unwrap_err(); - assert_eq!(err, PaymentError::MultipleDenoms {}.into()); - } - - #[test] - fn burning_sends_reserve() { - let mut deps = mock_dependencies(); - let curve_type = CurveType::Linear { - slope: Uint128::new(1), - scale: 1, - }; - setup_test(deps.as_mut(), 2, 8, curve_type.clone()); - - // succeeds with proper token (20 BTC = 20*10^8 satoshi) - let info = mock_info(INVESTOR, &coins(2_000_000_000, DENOM)); - let buy = ExecuteMsg::Buy {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap(); - - // bob got 2000 EPOXY (20.00) - assert_eq!(get_balance(deps.as_ref(), INVESTOR), Uint128::new(2000)); - - // cannot burn too much - let info = mock_info(INVESTOR, &[]); - let burn = ExecuteMsg::Burn { - amount: Uint128::new(3000), - }; - let err = execute(deps.as_mut(), mock_env(), info, burn).unwrap_err(); - assert_eq!( - err, - ContractError::Base(cw20_base::ContractError::Std(StdError::overflow( - OverflowError::new(OverflowOperation::Sub, 2000, 3000) - ))) - ); - - // burn 1000 EPOXY to get back 15BTC (*10^8) - let info = mock_info(INVESTOR, &[]); - let burn = ExecuteMsg::Burn { - amount: Uint128::new(1000), - }; - let res = execute(deps.as_mut(), mock_env(), info, burn).unwrap(); - - // balance is lower - assert_eq!(get_balance(deps.as_ref(), INVESTOR), Uint128::new(1000)); - - // ensure we got our money back - assert_eq!(1, res.messages.len()); - assert_eq!( - &res.messages[0], - &SubMsg::new(BankMsg::Send { - to_address: INVESTOR.into(), - amount: coins(1_500_000_000, DENOM), - }) - ); - - // check curve info updated - let curve = query_curve_info(deps.as_ref(), curve_type.to_curve_fn()).unwrap(); - assert_eq!(curve.reserve, Uint128::new(500_000_000)); - assert_eq!(curve.supply, Uint128::new(1000)); - assert_eq!(curve.spot_price, Decimal::percent(100)); - - // check token info updated - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(token.decimals, 2); - assert_eq!(token.total_supply, Uint128::new(1000)); - } - - #[test] - fn cw20_imports_work() { - let mut deps = mock_dependencies(); - let curve_type = CurveType::Constant { - value: Uint128::new(15), - scale: 1, - }; - setup_test(deps.as_mut(), 9, 6, curve_type); - - let alice: &str = "alice"; - let bob: &str = "bobby"; - let carl: &str = "carl"; - - // spend 45_000 uatom for 30_000_000 EPOXY - let info = mock_info(bob, &coins(45_000, DENOM)); - let buy = ExecuteMsg::Buy {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap(); - - // check balances - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(30_000_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::zero()); - - // send coins to carl - let bob_info = mock_info(bob, &[]); - let transfer = ExecuteMsg::Transfer { - recipient: carl.into(), - amount: Uint128::new(2_000_000), - }; - execute(deps.as_mut(), mock_env(), bob_info.clone(), transfer).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(28_000_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::new(2_000_000)); - - // allow alice - let allow = ExecuteMsg::IncreaseAllowance { - spender: alice.into(), - amount: Uint128::new(35_000_000), - expires: None, - }; - execute(deps.as_mut(), mock_env(), bob_info, allow).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(28_000_000)); - assert_eq!(get_balance(deps.as_ref(), alice), Uint128::zero()); - assert_eq!( - query_allowance(deps.as_ref(), bob.into(), alice.into()) - .unwrap() - .allowance, - Uint128::new(35_000_000) - ); - - // alice takes some for herself - let self_pay = ExecuteMsg::TransferFrom { - owner: bob.into(), - recipient: alice.into(), - amount: Uint128::new(25_000_000), - }; - let alice_info = mock_info(alice, &[]); - execute(deps.as_mut(), mock_env(), alice_info, self_pay).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(3_000_000)); - assert_eq!(get_balance(deps.as_ref(), alice), Uint128::new(25_000_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::new(2_000_000)); - assert_eq!( - query_allowance(deps.as_ref(), bob.into(), alice.into()) - .unwrap() - .allowance, - Uint128::new(10_000_000) - ); - - // test burn from works properly (burn tested in burning_sends_reserve) - // cannot burn more than they have - - let info = mock_info(alice, &[]); - let burn_from = ExecuteMsg::BurnFrom { - owner: bob.into(), - amount: Uint128::new(3_300_000), - }; - let err = execute(deps.as_mut(), mock_env(), info, burn_from).unwrap_err(); - assert_eq!( - err, - ContractError::Base(cw20_base::ContractError::Std(StdError::overflow( - OverflowError::new(OverflowOperation::Sub, 3000000, 3300000) - ))) - ); - - // burn 1_000_000 EPOXY to get back 1_500 DENOM (constant curve) - let info = mock_info(alice, &[]); - let burn_from = ExecuteMsg::BurnFrom { - owner: bob.into(), - amount: Uint128::new(1_000_000), - }; - let res = execute(deps.as_mut(), mock_env(), info, burn_from).unwrap(); - - // bob balance is lower, not alice - assert_eq!(get_balance(deps.as_ref(), alice), Uint128::new(25_000_000)); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(2_000_000)); - - // ensure alice got our money back - assert_eq!(1, res.messages.len()); - assert_eq!( - &res.messages[0], - &SubMsg::new(BankMsg::Send { - to_address: alice.into(), - amount: coins(1_500, DENOM), - }) - ); - } -} diff --git a/contracts/cw20-bonding/src/curves.rs b/contracts/cw20-bonding/src/curves.rs deleted file mode 100644 index b4617ab99..000000000 --- a/contracts/cw20-bonding/src/curves.rs +++ /dev/null @@ -1,357 +0,0 @@ -use integer_cbrt::IntegerCubeRoot; -use integer_sqrt::IntegerSquareRoot; -use rust_decimal::prelude::ToPrimitive; -use rust_decimal::Decimal; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; - -use cosmwasm_std::{Decimal as StdDecimal, Uint128}; - -/// This defines the curves we are using. -/// -/// I am struggling on what type to use for the math. Tokens are often stored as Uint128, -/// but they may have 6 or 9 digits. When using constant or linear functions, this doesn't matter -/// much, but for non-linear functions a lot more. Also, supply and reserve most likely have different -/// decimals... either we leave it for the callers to normalize and accept a `Decimal` input, -/// or we pass in `Uint128` as well as the decimal places for supply and reserve. -/// -/// After working the first route and realizing that `Decimal` is not all that great to work with -/// when you want to do more complex math than add and multiply `Uint128`, I decided to go the second -/// route. That made the signatures quite complex and my final idea was to pass in `supply_decimal` -/// and `reserve_decimal` in the curve constructors. -pub trait Curve { - /// Returns the spot price given the supply. - /// `f(x)` from the README - fn spot_price(&self, supply: Uint128) -> StdDecimal; - - /// Returns the total price paid up to purchase supply tokens (integral) - /// `F(x)` from the README - fn reserve(&self, supply: Uint128) -> Uint128; - - /// Inverse of reserve. Returns how many tokens would be issued - /// with a total paid amount of reserve. - /// `F^-1(x)` from the README - fn supply(&self, reserve: Uint128) -> Uint128; -} - -/// decimal returns an object = num * 10 ^ -scale -/// We use this function in contract.rs rather than call the crate constructor -/// itself, in case we want to swap out the implementation, we can do it only in this file. -pub fn decimal>(num: T, scale: u32) -> Decimal { - Decimal::from_i128_with_scale(num.into() as i128, scale) -} - -/// StdDecimal stores as a u128 with 18 decimal points of precision -fn decimal_to_std(x: Decimal) -> StdDecimal { - // this seems straight-forward (if inefficient), converting via string representation - // TODO: execute errors better? Result? - StdDecimal::from_str(&x.to_string()).unwrap() - - // // maybe a better approach doing math, not sure about rounding - // - // // try to preserve decimal points, max 9 - // let digits = min(x.scale(), 9); - // let multiplier = 10u128.pow(digits); - // - // // we multiply up before we round off to u128, - // // let StdDecimal do its best to keep these decimal places - // let nominator = (x * decimal(multiplier, 0)).to_u128().unwrap(); - // StdDecimal::from_ratio(nominator, multiplier) -} - -/// spot price is always a constant value -pub struct Constant { - pub value: Decimal, - pub normalize: DecimalPlaces, -} - -impl Constant { - pub fn new(value: Decimal, normalize: DecimalPlaces) -> Self { - Self { value, normalize } - } -} - -impl Curve for Constant { - // we need to normalize value with the reserve decimal places - // (eg 0.1 value would return 100_000 if reserve was uatom) - fn spot_price(&self, _supply: Uint128) -> StdDecimal { - // f(x) = self.value - decimal_to_std(self.value) - } - - /// Returns total number of reserve tokens needed to purchase a given number of supply tokens. - /// Note that both need to be normalized. - fn reserve(&self, supply: Uint128) -> Uint128 { - // f(x) = supply * self.value - let reserve = self.normalize.from_supply(supply) * self.value; - self.normalize.to_reserve(reserve) - } - - fn supply(&self, reserve: Uint128) -> Uint128 { - // f(x) = reserve / self.value - let supply = self.normalize.from_reserve(reserve) / self.value; - self.normalize.to_supply(supply) - } -} - -/// spot_price is slope * supply -pub struct Linear { - pub slope: Decimal, - pub normalize: DecimalPlaces, -} - -impl Linear { - pub fn new(slope: Decimal, normalize: DecimalPlaces) -> Self { - Self { slope, normalize } - } -} - -impl Curve for Linear { - fn spot_price(&self, supply: Uint128) -> StdDecimal { - // f(x) = supply * self.value - let out = self.normalize.from_supply(supply) * self.slope; - decimal_to_std(out) - } - - fn reserve(&self, supply: Uint128) -> Uint128 { - // f(x) = self.slope * supply * supply / 2 - let normalized = self.normalize.from_supply(supply); - let square = normalized * normalized; - // Note: multiplying by 0.5 is much faster than dividing by 2 - let reserve = square * self.slope * Decimal::new(5, 1); - self.normalize.to_reserve(reserve) - } - - fn supply(&self, reserve: Uint128) -> Uint128 { - // f(x) = (2 * reserve / self.slope) ^ 0.5 - // note: use addition here to optimize 2* operation - let square = self.normalize.from_reserve(reserve + reserve) / self.slope; - let supply = square_root(square); - self.normalize.to_supply(supply) - } -} - -/// spot_price is slope * (supply)^0.5 -pub struct SquareRoot { - pub slope: Decimal, - pub normalize: DecimalPlaces, -} - -impl SquareRoot { - pub fn new(slope: Decimal, normalize: DecimalPlaces) -> Self { - Self { slope, normalize } - } -} - -impl Curve for SquareRoot { - fn spot_price(&self, supply: Uint128) -> StdDecimal { - // f(x) = self.slope * supply^0.5 - let square = self.normalize.from_supply(supply); - let root = square_root(square); - decimal_to_std(root * self.slope) - } - - fn reserve(&self, supply: Uint128) -> Uint128 { - // f(x) = self.slope * supply * supply^0.5 / 1.5 - let normalized = self.normalize.from_supply(supply); - let root = square_root(normalized); - let reserve = self.slope * normalized * root / Decimal::new(15, 1); - self.normalize.to_reserve(reserve) - } - - fn supply(&self, reserve: Uint128) -> Uint128 { - // f(x) = (1.5 * reserve / self.slope) ^ (2/3) - let base = self.normalize.from_reserve(reserve) * Decimal::new(15, 1) / self.slope; - let squared = base * base; - let supply = cube_root(squared); - self.normalize.to_supply(supply) - } -} - -// we multiply by 10^18, turn to int, take square root, then divide by 10^9 as we convert back to decimal -fn square_root(square: Decimal) -> Decimal { - // must be even - // TODO: this can overflow easily at 18... what is a good value? - const EXTRA_DIGITS: u32 = 12; - let multiplier = 10u128.saturating_pow(EXTRA_DIGITS); - - // multiply by 10^18 and turn to u128 - let extended = square * decimal(multiplier, 0); - let extended = extended.floor().to_u128().unwrap(); - - // take square root, and build a decimal again - let root = extended.integer_sqrt(); - decimal(root, EXTRA_DIGITS / 2) -} - -// we multiply by 10^9, turn to int, take cube root, then divide by 10^3 as we convert back to decimal -fn cube_root(cube: Decimal) -> Decimal { - // must be multiple of 3 - // TODO: what is a good value? - const EXTRA_DIGITS: u32 = 9; - let multiplier = 10u128.saturating_pow(EXTRA_DIGITS); - - // multiply out and turn to u128 - let extended = cube * decimal(multiplier, 0); - let extended = extended.floor().to_u128().unwrap(); - - // take cube root, and build a decimal again - let root = extended.integer_cbrt(); - decimal(root, EXTRA_DIGITS / 3) -} - -/// DecimalPlaces should be passed into curve constructors -#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, JsonSchema, Default)] -pub struct DecimalPlaces { - /// Number of decimal places for the supply token (this is what was passed in cw20-base instantiate - pub supply: u32, - /// Number of decimal places for the reserve token (eg. 6 for uatom, 9 for nstep, 18 for wei) - pub reserve: u32, -} - -impl DecimalPlaces { - pub fn new(supply: u8, reserve: u8) -> Self { - DecimalPlaces { - supply: supply as u32, - reserve: reserve as u32, - } - } - - pub fn to_reserve(self, reserve: Decimal) -> Uint128 { - let factor = decimal(10u128.pow(self.reserve), 0); - let out = reserve * factor; - // TODO: execute overflow better? Result? - out.floor().to_u128().unwrap().into() - } - - pub fn to_supply(self, supply: Decimal) -> Uint128 { - let factor = decimal(10u128.pow(self.supply), 0); - let out = supply * factor; - // TODO: execute overflow better? Result? - out.floor().to_u128().unwrap().into() - } - - pub fn from_supply(&self, supply: Uint128) -> Decimal { - decimal(supply, self.supply) - } - - pub fn from_reserve(&self, reserve: Uint128) -> Decimal { - decimal(reserve, self.reserve) - } -} - -#[cfg(test)] -mod tests { - use super::*; - // TODO: test DecimalPlaces return proper decimals - - #[test] - fn constant_curve() { - // supply is nstep (9), reserve is uatom (6) - let normalize = DecimalPlaces::new(9, 6); - let curve = Constant::new(decimal(15u128, 1), normalize); - - // do some sanity checks.... - // spot price is always 1.5 ATOM - assert_eq!( - StdDecimal::percent(150), - curve.spot_price(Uint128::new(123)) - ); - - // if we have 30 STEP, we should have 45 ATOM - let reserve = curve.reserve(Uint128::new(30_000_000_000)); - assert_eq!(Uint128::new(45_000_000), reserve); - - // if we have 36 ATOM, we should have 24 STEP - let supply = curve.supply(Uint128::new(36_000_000)); - assert_eq!(Uint128::new(24_000_000_000), supply); - } - - #[test] - fn linear_curve() { - // supply is usdt (2), reserve is btc (8) - let normalize = DecimalPlaces::new(2, 8); - // slope is 0.1 (eg hits 1.0 after 10btc) - let curve = Linear::new(decimal(1u128, 1), normalize); - - // do some sanity checks.... - // spot price is 0.1 with 1 USDT supply - assert_eq!( - StdDecimal::permille(100), - curve.spot_price(Uint128::new(100)) - ); - // spot price is 1.7 with 17 USDT supply - assert_eq!( - StdDecimal::permille(1700), - curve.spot_price(Uint128::new(1700)) - ); - // spot price is 0.212 with 2.12 USDT supply - assert_eq!( - StdDecimal::permille(212), - curve.spot_price(Uint128::new(212)) - ); - - // if we have 10 USDT, we should have 5 BTC - let reserve = curve.reserve(Uint128::new(1000)); - assert_eq!(Uint128::new(500_000_000), reserve); - // if we have 20 USDT, we should have 20 BTC - let reserve = curve.reserve(Uint128::new(2000)); - assert_eq!(Uint128::new(2_000_000_000), reserve); - - // if we have 1.25 BTC, we should have 5 USDT - let supply = curve.supply(Uint128::new(125_000_000)); - assert_eq!(Uint128::new(500), supply); - // test square root rounding - // TODO: test when supply has many more decimal places than reserve - // if we have 1.11 BTC, we should have 4.7116875957... USDT - let supply = curve.supply(Uint128::new(111_000_000)); - assert_eq!(Uint128::new(471), supply); - } - - #[test] - fn sqrt_curve() { - // supply is utree (6) reserve is chf (2) - let normalize = DecimalPlaces::new(6, 2); - // slope is 0.35 (eg hits 0.35 after 1 chf, 3.5 after 100chf) - let curve = SquareRoot::new(decimal(35u128, 2), normalize); - - // do some sanity checks.... - // spot price is 0.35 with 1 TREE supply - assert_eq!( - StdDecimal::percent(35), - curve.spot_price(Uint128::new(1_000_000)) - ); - // spot price is 3.5 with 100 TREE supply - assert_eq!( - StdDecimal::percent(350), - curve.spot_price(Uint128::new(100_000_000)) - ); - // spot price should be 23.478713763747788 with 4500 TREE supply (test rounding and reporting here) - // rounds off around 8-9 sig figs (note diff for last points) - assert_eq!( - StdDecimal::from_ratio(2347871365u128, 100_000_000u128), - curve.spot_price(Uint128::new(4_500_000_000)) - ); - - // if we have 1 TREE, we should have 0.2333333333333 CHF - let reserve = curve.reserve(Uint128::new(1_000_000)); - assert_eq!(Uint128::new(23), reserve); - // if we have 100 TREE, we should have 233.333333333 CHF - let reserve = curve.reserve(Uint128::new(100_000_000)); - assert_eq!(Uint128::new(23_333), reserve); - // test rounding - // if we have 235 TREE, we should have 840.5790828021146 CHF - let reserve = curve.reserve(Uint128::new(235_000_000)); - assert_eq!(Uint128::new(84_057), reserve); // round down - - // // if we have 0.23 CHF, we should have 0.990453 TREE (round down) - let supply = curve.supply(Uint128::new(23)); - assert_eq!(Uint128::new(990_000), supply); - // if we have 840.58 CHF, we should have 235.000170 TREE (round down) - let supply = curve.supply(Uint128::new(84058)); - assert_eq!(Uint128::new(235_000_000), supply); - } - - // Idea: generic test that curve.supply(curve.reserve(supply)) == supply (or within some small rounding margin) -} diff --git a/contracts/cw20-bonding/src/error.rs b/contracts/cw20-bonding/src/error.rs deleted file mode 100644 index aa6bcc9ab..000000000 --- a/contracts/cw20-bonding/src/error.rs +++ /dev/null @@ -1,18 +0,0 @@ -use cosmwasm_std::StdError; -use cw_utils::PaymentError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Base(#[from] cw20_base::ContractError), - - #[error("{0}")] - Payment(#[from] PaymentError), - - #[error("Unauthorized")] - Unauthorized {}, -} diff --git a/contracts/cw20-bonding/src/lib.rs b/contracts/cw20-bonding/src/lib.rs deleted file mode 100644 index 8ecd1fa67..000000000 --- a/contracts/cw20-bonding/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod contract; -pub mod curves; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/contracts/cw20-bonding/src/msg.rs b/contracts/cw20-bonding/src/msg.rs deleted file mode 100644 index 3bb201c4a..000000000 --- a/contracts/cw20-bonding/src/msg.rs +++ /dev/null @@ -1,145 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::curves::{decimal, Constant, Curve, DecimalPlaces, Linear, SquareRoot}; -use cosmwasm_std::{Binary, Decimal, Uint128}; -use cw20::Expiration; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - /// name of the supply token - pub name: String, - /// symbol / ticker of the supply token - pub symbol: String, - /// number of decimal places of the supply token, needed for proper curve math. - /// If it is eg. BTC, where a balance of 10^8 means 1 BTC, then use 8 here. - pub decimals: u8, - - /// this is the reserve token denom (only support native for now) - pub reserve_denom: String, - /// number of decimal places for the reserve token, needed for proper curve math. - /// Same format as decimals above, eg. if it is uatom, where 1 unit is 10^-6 ATOM, use 6 here - pub reserve_decimals: u8, - - /// enum to store the curve parameters used for this contract - /// if you want to add a custom Curve, you should make a new contract that imports this one. - /// write a custom `instantiate`, and then dispatch `your::execute` -> `cw20_bonding::do_execute` - /// with your custom curve as a parameter (and same with `query` -> `do_query`) - pub curve_type: CurveType, -} - -pub type CurveFn = Box Box>; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum CurveType { - /// Constant always returns `value * 10^-scale` as spot price - Constant { value: Uint128, scale: u32 }, - /// Linear returns `slope * 10^-scale * supply` as spot price - Linear { slope: Uint128, scale: u32 }, - /// SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price - SquareRoot { slope: Uint128, scale: u32 }, -} - -impl CurveType { - pub fn to_curve_fn(&self) -> CurveFn { - match self.clone() { - CurveType::Constant { value, scale } => { - let calc = move |places| -> Box { - Box::new(Constant::new(decimal(value, scale), places)) - }; - Box::new(calc) - } - CurveType::Linear { slope, scale } => { - let calc = move |places| -> Box { - Box::new(Linear::new(decimal(slope, scale), places)) - }; - Box::new(calc) - } - CurveType::SquareRoot { slope, scale } => { - let calc = move |places| -> Box { - Box::new(SquareRoot::new(decimal(slope, scale), places)) - }; - Box::new(calc) - } - } - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - /// Buy will attempt to purchase as many supply tokens as possible. - /// You must send only reserve tokens in that message - Buy {}, - - /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions - Transfer { recipient: String, amount: Uint128 }, - /// Implements CW20. Burn is a base message to destroy tokens forever - Burn { amount: Uint128 }, - /// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action - /// on the receiving contract. - Send { - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens - /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance - /// expiration with this one. - IncreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Lowers the spender's access of tokens - /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current - /// allowance expiration with this one. - DecreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient - /// if `env.sender` has sufficient pre-approval. - TransferFrom { - owner: String, - recipient: String, - amount: Uint128, - }, - /// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract - /// if `env.sender` has sufficient pre-approval. - SendFrom { - owner: String, - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Destroys tokens forever - BurnFrom { owner: String, amount: Uint128 }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Returns the reserve and supply quantities, as well as the spot price to buy 1 token - CurveInfo {}, - - /// Implements CW20. Returns the current balance of the given address, 0 if unset. - Balance { address: String }, - /// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc. - TokenInfo {}, - /// Implements CW20 "allowance" extension. - /// Returns how much spender can use from owner account, 0 if unset. - Allowance { owner: String, spender: String }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct CurveInfoResponse { - // how many reserve tokens have been received - pub reserve: Uint128, - // how many supply tokens have been issued - pub supply: Uint128, - pub spot_price: Decimal, - pub reserve_denom: String, -} diff --git a/contracts/cw20-bonding/src/state.rs b/contracts/cw20-bonding/src/state.rs deleted file mode 100644 index 1a54d43de..000000000 --- a/contracts/cw20-bonding/src/state.rs +++ /dev/null @@ -1,38 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Uint128; -use cw_storage_plus::Item; - -use crate::curves::DecimalPlaces; -use crate::msg::CurveType; - -/// Supply is dynamic and tracks the current supply of staked and ERC20 tokens. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)] -pub struct CurveState { - /// reserve is how many native tokens exist bonded to the validator - pub reserve: Uint128, - /// supply is how many tokens this contract has issued - pub supply: Uint128, - - // the denom of the reserve token - pub reserve_denom: String, - - // how to normalize reserve and supply - pub decimals: DecimalPlaces, -} - -impl CurveState { - pub fn new(reserve_denom: String, decimals: DecimalPlaces) -> Self { - CurveState { - reserve: Uint128::zero(), - supply: Uint128::zero(), - reserve_denom, - decimals, - } - } -} - -pub const CURVE_STATE: Item = Item::new("curve_state"); - -pub const CURVE_TYPE: Item = Item::new("curve_type"); diff --git a/contracts/cw20-escrow/.cargo/config b/contracts/cw20-escrow/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/contracts/cw20-escrow/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/contracts/cw20-escrow/Cargo.toml b/contracts/cw20-escrow/Cargo.toml deleted file mode 100644 index 1f5f93afa..000000000 --- a/contracts/cw20-escrow/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "cw20-escrow" -version = "0.11.1" -authors = ["Ethan Frey "] -edition = "2018" -description = "Implementation of an escrow that accepts CosmWasm-20 tokens as well as native tokens" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } -cw20-base = { path = "../cw20-base", version = "0.11.1", features = ["library"] } diff --git a/contracts/cw20-escrow/NOTICE b/contracts/cw20-escrow/NOTICE deleted file mode 100644 index 8e53cb532..000000000 --- a/contracts/cw20-escrow/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-Escrow: A CosmWasm escrow contract that handles native and cw20 tokens -Copyright (C) 2020 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-escrow/README.md b/contracts/cw20-escrow/README.md deleted file mode 100644 index 3b04148ac..000000000 --- a/contracts/cw20-escrow/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# CW20 Escrow - -This is an escrow meta-contract that allows multiple users to -create independent escrows. Each escrow has a sender, recipient, -and arbiter. It also has a unique id (for future calls to reference it) -and an optional timeout. - -The basic function is the sender creates an escrow with funds. -The arbiter may at any time decide to release the funds to either -the intended recipient or the original sender (but no one else), -and if it passes with optional timeout, anyone can refund the locked -tokens to the original sender. - -We also add a function called "top_up", which allows anyone to add more -funds to the contract at any time. - -## Token types - -This contract is meant not just to be functional, but also to work as a simple -example of an CW20 "Receiver". And demonstrate how the same calls can be fed -native tokens (via typical `ExecuteMsg` route), or cw20 tokens (via `Receiver` interface). - -Both `create` and `top_up` can be called directly (with a payload of native tokens), -or from a cw20 contract using the [Receiver Interface](../../packages/cw20/README.md#receiver). -This means we can load the escrow with any number of native or cw20 tokens (or a mix), -allow of which get released when the arbiter decides. - -## Running this contract - -You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. - -You can run unit tests on this via: - -`cargo test` - -Once you are happy with the content, you can compile it to wasm via: - -``` -RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw20_escrow.wasm . -ls -l cw20_escrow.wasm -sha256sum cw20_escrow.wasm -``` - -Or for a production-ready (optimized) build, run a build command in the -the repository root: https://github.com/CosmWasm/cw-plus#compiling. diff --git a/contracts/cw20-escrow/examples/schema.rs b/contracts/cw20-escrow/examples/schema.rs deleted file mode 100644 index e290178b2..000000000 --- a/contracts/cw20-escrow/examples/schema.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20_escrow::msg::{ - DetailsResponse, ExecuteMsg, InstantiateMsg, ListResponse, QueryMsg, ReceiveMsg, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(ReceiveMsg), &out_dir); - export_schema(&schema_for!(DetailsResponse), &out_dir); - export_schema(&schema_for!(ListResponse), &out_dir); -} diff --git a/contracts/cw20-escrow/src/contract.rs b/contracts/cw20-escrow/src/contract.rs deleted file mode 100644 index f7d477ebf..000000000 --- a/contracts/cw20-escrow/src/contract.rs +++ /dev/null @@ -1,603 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - from_binary, to_binary, Addr, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, - StdResult, SubMsg, WasmMsg, -}; - -use cw2::set_contract_version; -use cw20::{Balance, Cw20Coin, Cw20CoinVerified, Cw20ExecuteMsg, Cw20ReceiveMsg}; - -use crate::error::ContractError; -use crate::msg::{ - CreateMsg, DetailsResponse, ExecuteMsg, InstantiateMsg, ListResponse, QueryMsg, ReceiveMsg, -}; -use crate::state::{all_escrow_ids, Escrow, GenericBalance, ESCROWS}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw20-escrow"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: InstantiateMsg, -) -> StdResult { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // no setup - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Create(msg) => { - execute_create(deps, msg, Balance::from(info.funds), &info.sender) - } - ExecuteMsg::Approve { id } => execute_approve(deps, env, info, id), - ExecuteMsg::TopUp { id } => execute_top_up(deps, id, Balance::from(info.funds)), - ExecuteMsg::Refund { id } => execute_refund(deps, env, info, id), - ExecuteMsg::Receive(msg) => execute_receive(deps, info, msg), - } -} - -pub fn execute_receive( - deps: DepsMut, - info: MessageInfo, - wrapper: Cw20ReceiveMsg, -) -> Result { - let msg: ReceiveMsg = from_binary(&wrapper.msg)?; - let balance = Balance::Cw20(Cw20CoinVerified { - address: info.sender, - amount: wrapper.amount, - }); - let api = deps.api; - match msg { - ReceiveMsg::Create(msg) => { - execute_create(deps, msg, balance, &api.addr_validate(&wrapper.sender)?) - } - ReceiveMsg::TopUp { id } => execute_top_up(deps, id, balance), - } -} - -pub fn execute_create( - deps: DepsMut, - msg: CreateMsg, - balance: Balance, - sender: &Addr, -) -> Result { - if balance.is_empty() { - return Err(ContractError::EmptyBalance {}); - } - - let mut cw20_whitelist = msg.addr_whitelist(deps.api)?; - - let escrow_balance = match balance { - Balance::Native(balance) => GenericBalance { - native: balance.0, - cw20: vec![], - }, - Balance::Cw20(token) => { - // make sure the token sent is on the whitelist by default - if !cw20_whitelist.iter().any(|t| t == &token.address) { - cw20_whitelist.push(token.address.clone()) - } - GenericBalance { - native: vec![], - cw20: vec![token], - } - } - }; - - let escrow = Escrow { - arbiter: deps.api.addr_validate(&msg.arbiter)?, - recipient: deps.api.addr_validate(&msg.recipient)?, - source: sender.clone(), - end_height: msg.end_height, - end_time: msg.end_time, - balance: escrow_balance, - cw20_whitelist, - }; - - // try to store it, fail if the id was already in use - ESCROWS.update(deps.storage, &msg.id, |existing| match existing { - None => Ok(escrow), - Some(_) => Err(ContractError::AlreadyInUse {}), - })?; - - let res = Response::new().add_attributes(vec![("action", "create"), ("id", msg.id.as_str())]); - Ok(res) -} - -pub fn execute_top_up( - deps: DepsMut, - id: String, - balance: Balance, -) -> Result { - if balance.is_empty() { - return Err(ContractError::EmptyBalance {}); - } - // this fails is no escrow there - let mut escrow = ESCROWS.load(deps.storage, &id)?; - - if let Balance::Cw20(token) = &balance { - // ensure the token is on the whitelist - if !escrow.cw20_whitelist.iter().any(|t| t == &token.address) { - return Err(ContractError::NotInWhitelist {}); - } - }; - - escrow.balance.add_tokens(balance); - - // and save - ESCROWS.save(deps.storage, &id, &escrow)?; - - let res = Response::new().add_attributes(vec![("action", "top_up"), ("id", id.as_str())]); - Ok(res) -} - -pub fn execute_approve( - deps: DepsMut, - env: Env, - info: MessageInfo, - id: String, -) -> Result { - // this fails is no escrow there - let escrow = ESCROWS.load(deps.storage, &id)?; - - if info.sender != escrow.arbiter { - Err(ContractError::Unauthorized {}) - } else if escrow.is_expired(&env) { - Err(ContractError::Expired {}) - } else { - // we delete the escrow - ESCROWS.remove(deps.storage, &id); - - // send all tokens out - let messages: Vec = send_tokens(&escrow.recipient, &escrow.balance)?; - - Ok(Response::new() - .add_attribute("action", "approve") - .add_attribute("id", id) - .add_attribute("to", escrow.recipient) - .add_submessages(messages)) - } -} - -pub fn execute_refund( - deps: DepsMut, - env: Env, - info: MessageInfo, - id: String, -) -> Result { - // this fails is no escrow there - let escrow = ESCROWS.load(deps.storage, &id)?; - - // the arbiter can send anytime OR anyone can send after expiration - if !escrow.is_expired(&env) && info.sender != escrow.arbiter { - Err(ContractError::Unauthorized {}) - } else { - // we delete the escrow - ESCROWS.remove(deps.storage, &id); - - // send all tokens out - let messages = send_tokens(&escrow.source, &escrow.balance)?; - - Ok(Response::new() - .add_attribute("action", "refund") - .add_attribute("id", id) - .add_attribute("to", escrow.source) - .add_submessages(messages)) - } -} - -fn send_tokens(to: &Addr, balance: &GenericBalance) -> StdResult> { - let native_balance = &balance.native; - let mut msgs: Vec = if native_balance.is_empty() { - vec![] - } else { - vec![SubMsg::new(BankMsg::Send { - to_address: to.into(), - amount: native_balance.to_vec(), - })] - }; - - let cw20_balance = &balance.cw20; - let cw20_msgs: StdResult> = cw20_balance - .iter() - .map(|c| { - let msg = Cw20ExecuteMsg::Transfer { - recipient: to.into(), - amount: c.amount, - }; - let exec = SubMsg::new(WasmMsg::Execute { - contract_addr: c.address.to_string(), - msg: to_binary(&msg)?, - funds: vec![], - }); - Ok(exec) - }) - .collect(); - msgs.append(&mut cw20_msgs?); - Ok(msgs) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::List {} => to_binary(&query_list(deps)?), - QueryMsg::Details { id } => to_binary(&query_details(deps, id)?), - } -} - -fn query_details(deps: Deps, id: String) -> StdResult { - let escrow = ESCROWS.load(deps.storage, &id)?; - - let cw20_whitelist = escrow.human_whitelist(); - - // transform tokens - let native_balance = escrow.balance.native; - - let cw20_balance: StdResult> = escrow - .balance - .cw20 - .into_iter() - .map(|token| { - Ok(Cw20Coin { - address: token.address.into(), - amount: token.amount, - }) - }) - .collect(); - - let details = DetailsResponse { - id, - arbiter: escrow.arbiter.into(), - recipient: escrow.recipient.into(), - source: escrow.source.into(), - end_height: escrow.end_height, - end_time: escrow.end_time, - native_balance, - cw20_balance: cw20_balance?, - cw20_whitelist, - }; - Ok(details) -} - -fn query_list(deps: Deps) -> StdResult { - Ok(ListResponse { - escrows: all_escrow_ids(deps.storage)?, - }) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coin, coins, CosmosMsg, StdError, Uint128}; - - use crate::msg::ExecuteMsg::TopUp; - - use super::*; - - #[test] - fn happy_path_native() { - let mut deps = mock_dependencies(); - - // instantiate an empty contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info(&String::from("anyone"), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // create an escrow - let create = CreateMsg { - id: "foobar".to_string(), - arbiter: String::from("arbitrate"), - recipient: String::from("recd"), - end_time: None, - end_height: Some(123456), - cw20_whitelist: None, - }; - let sender = String::from("source"); - let balance = coins(100, "tokens"); - let info = mock_info(&sender, &balance); - let msg = ExecuteMsg::Create(create.clone()); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // ensure the details is what we expect - let details = query_details(deps.as_ref(), "foobar".to_string()).unwrap(); - assert_eq!( - details, - DetailsResponse { - id: "foobar".to_string(), - arbiter: String::from("arbitrate"), - recipient: String::from("recd"), - source: String::from("source"), - end_height: Some(123456), - end_time: None, - native_balance: balance.clone(), - cw20_balance: vec![], - cw20_whitelist: vec![], - } - ); - - // approve it - let id = create.id.clone(); - let info = mock_info(&create.arbiter, &[]); - let res = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Approve { id }).unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!(("action", "approve"), res.attributes[0]); - assert_eq!( - res.messages[0], - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: create.recipient, - amount: balance, - })) - ); - - // second attempt fails (not found) - let id = create.id.clone(); - let info = mock_info(&create.arbiter, &[]); - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Approve { id }).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - } - - #[test] - fn happy_path_cw20() { - let mut deps = mock_dependencies(); - - // instantiate an empty contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info(&String::from("anyone"), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // create an escrow - let create = CreateMsg { - id: "foobar".to_string(), - arbiter: String::from("arbitrate"), - recipient: String::from("recd"), - end_time: None, - end_height: None, - cw20_whitelist: Some(vec![String::from("other-token")]), - }; - let receive = Cw20ReceiveMsg { - sender: String::from("source"), - amount: Uint128::new(100), - msg: to_binary(&ExecuteMsg::Create(create.clone())).unwrap(), - }; - let token_contract = String::from("my-cw20-token"); - let info = mock_info(&token_contract, &[]); - let msg = ExecuteMsg::Receive(receive.clone()); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // ensure the whitelist is what we expect - let details = query_details(deps.as_ref(), "foobar".to_string()).unwrap(); - assert_eq!( - details, - DetailsResponse { - id: "foobar".to_string(), - arbiter: String::from("arbitrate"), - recipient: String::from("recd"), - source: String::from("source"), - end_height: None, - end_time: None, - native_balance: vec![], - cw20_balance: vec![Cw20Coin { - address: String::from("my-cw20-token"), - amount: Uint128::new(100), - }], - cw20_whitelist: vec![String::from("other-token"), String::from("my-cw20-token")], - } - ); - - // approve it - let id = create.id.clone(); - let info = mock_info(&create.arbiter, &[]); - let res = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Approve { id }).unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!(("action", "approve"), res.attributes[0]); - let send_msg = Cw20ExecuteMsg::Transfer { - recipient: create.recipient, - amount: receive.amount, - }; - assert_eq!( - res.messages[0], - SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: token_contract, - msg: to_binary(&send_msg).unwrap(), - funds: vec![] - })) - ); - - // second attempt fails (not found) - let id = create.id.clone(); - let info = mock_info(&create.arbiter, &[]); - let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Approve { id }).unwrap_err(); - assert!(matches!(err, ContractError::Std(StdError::NotFound { .. }))); - } - - #[test] - fn add_tokens_proper() { - let mut tokens = GenericBalance::default(); - tokens.add_tokens(Balance::from(vec![coin(123, "atom"), coin(789, "eth")])); - tokens.add_tokens(Balance::from(vec![coin(456, "atom"), coin(12, "btc")])); - assert_eq!( - tokens.native, - vec![coin(579, "atom"), coin(789, "eth"), coin(12, "btc")] - ); - } - - #[test] - fn add_cw_tokens_proper() { - let mut tokens = GenericBalance::default(); - let bar_token = Addr::unchecked("bar_token"); - let foo_token = Addr::unchecked("foo_token"); - tokens.add_tokens(Balance::Cw20(Cw20CoinVerified { - address: foo_token.clone(), - amount: Uint128::new(12345), - })); - tokens.add_tokens(Balance::Cw20(Cw20CoinVerified { - address: bar_token.clone(), - amount: Uint128::new(777), - })); - tokens.add_tokens(Balance::Cw20(Cw20CoinVerified { - address: foo_token.clone(), - amount: Uint128::new(23400), - })); - assert_eq!( - tokens.cw20, - vec![ - Cw20CoinVerified { - address: foo_token, - amount: Uint128::new(35745), - }, - Cw20CoinVerified { - address: bar_token, - amount: Uint128::new(777), - } - ] - ); - } - - #[test] - fn top_up_mixed_tokens() { - let mut deps = mock_dependencies(); - - // instantiate an empty contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info(&String::from("anyone"), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // only accept these tokens - let whitelist = vec![String::from("bar_token"), String::from("foo_token")]; - - // create an escrow with 2 native tokens - let create = CreateMsg { - id: "foobar".to_string(), - arbiter: String::from("arbitrate"), - recipient: String::from("recd"), - end_time: None, - end_height: None, - cw20_whitelist: Some(whitelist), - }; - let sender = String::from("source"); - let balance = vec![coin(100, "fee"), coin(200, "stake")]; - let info = mock_info(&sender, &balance); - let msg = ExecuteMsg::Create(create.clone()); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "create"), res.attributes[0]); - - // top it up with 2 more native tokens - let extra_native = vec![coin(250, "random"), coin(300, "stake")]; - let info = mock_info(&sender, &extra_native); - let top_up = ExecuteMsg::TopUp { - id: create.id.clone(), - }; - let res = execute(deps.as_mut(), mock_env(), info, top_up).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "top_up"), res.attributes[0]); - - // top up with one foreign token - let bar_token = String::from("bar_token"); - let base = TopUp { - id: create.id.clone(), - }; - let top_up = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: String::from("random"), - amount: Uint128::new(7890), - msg: to_binary(&base).unwrap(), - }); - let info = mock_info(&bar_token, &[]); - let res = execute(deps.as_mut(), mock_env(), info, top_up).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "top_up"), res.attributes[0]); - - // top with a foreign token not on the whitelist - // top up with one foreign token - let baz_token = String::from("baz_token"); - let base = TopUp { - id: create.id.clone(), - }; - let top_up = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: String::from("random"), - amount: Uint128::new(7890), - msg: to_binary(&base).unwrap(), - }); - let info = mock_info(&baz_token, &[]); - let err = execute(deps.as_mut(), mock_env(), info, top_up).unwrap_err(); - assert_eq!(err, ContractError::NotInWhitelist {}); - - // top up with second foreign token - let foo_token = String::from("foo_token"); - let base = TopUp { - id: create.id.clone(), - }; - let top_up = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: String::from("random"), - amount: Uint128::new(888), - msg: to_binary(&base).unwrap(), - }); - let info = mock_info(&foo_token, &[]); - let res = execute(deps.as_mut(), mock_env(), info, top_up).unwrap(); - assert_eq!(0, res.messages.len()); - assert_eq!(("action", "top_up"), res.attributes[0]); - - // approve it - let id = create.id.clone(); - let info = mock_info(&create.arbiter, &[]); - let res = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Approve { id }).unwrap(); - assert_eq!(("action", "approve"), res.attributes[0]); - assert_eq!(3, res.messages.len()); - - // first message releases all native coins - assert_eq!( - res.messages[0], - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: create.recipient.clone(), - amount: vec![coin(100, "fee"), coin(500, "stake"), coin(250, "random")], - })) - ); - - // second one release bar cw20 token - let send_msg = Cw20ExecuteMsg::Transfer { - recipient: create.recipient.clone(), - amount: Uint128::new(7890), - }; - assert_eq!( - res.messages[1], - SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: bar_token, - msg: to_binary(&send_msg).unwrap(), - funds: vec![] - })) - ); - - // third one release foo cw20 token - let send_msg = Cw20ExecuteMsg::Transfer { - recipient: create.recipient, - amount: Uint128::new(888), - }; - assert_eq!( - res.messages[2], - SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: foo_token, - msg: to_binary(&send_msg).unwrap(), - funds: vec![] - })) - ); - } -} diff --git a/contracts/cw20-escrow/src/error.rs b/contracts/cw20-escrow/src/error.rs deleted file mode 100644 index 69e258ccf..000000000 --- a/contracts/cw20-escrow/src/error.rs +++ /dev/null @@ -1,23 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Only accepts tokens in the cw20_whitelist")] - NotInWhitelist {}, - - #[error("Escrow is expired")] - Expired {}, - - #[error("Send some coins to create an escrow")] - EmptyBalance {}, - - #[error("Escrow id already in use")] - AlreadyInUse {}, -} diff --git a/contracts/cw20-escrow/src/integration_test.rs b/contracts/cw20-escrow/src/integration_test.rs deleted file mode 100644 index 44ffab45a..000000000 --- a/contracts/cw20-escrow/src/integration_test.rs +++ /dev/null @@ -1,151 +0,0 @@ -#![cfg(test)] - -use cosmwasm_std::{coins, to_binary, Addr, Empty, Uint128}; -use cw20::{Cw20Coin, Cw20Contract, Cw20ExecuteMsg}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; - -use crate::msg::{CreateMsg, DetailsResponse, ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg}; - -pub fn contract_escrow() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - -pub fn contract_cw20() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -#[test] -// receive cw20 tokens and release upon approval -fn escrow_happy_path_cw20_tokens() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = coins(2000, "btc"); - - let mut router = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up cw20 contract with some tokens - let cw20_id = router.store_code(contract_cw20()); - let msg = cw20_base::msg::InstantiateMsg { - name: "Cash Money".to_string(), - symbol: "CASH".to_string(), - decimals: 2, - initial_balances: vec![Cw20Coin { - address: owner.to_string(), - amount: Uint128::new(5000), - }], - mint: None, - marketing: None, - }; - let cash_addr = router - .instantiate_contract(cw20_id, owner.clone(), &msg, &[], "CASH", None) - .unwrap(); - - // set up reflect contract - let escrow_id = router.store_code(contract_escrow()); - let escrow_addr = router - .instantiate_contract( - escrow_id, - owner.clone(), - &InstantiateMsg {}, - &[], - "Escrow", - None, - ) - .unwrap(); - - // they are different - assert_ne!(cash_addr, escrow_addr); - - // set up cw20 helpers - let cash = Cw20Contract(cash_addr.clone()); - - // ensure our balances - let owner_balance = cash.balance(&router, owner.clone()).unwrap(); - assert_eq!(owner_balance, Uint128::new(5000)); - let escrow_balance = cash.balance(&router, escrow_addr.clone()).unwrap(); - assert_eq!(escrow_balance, Uint128::zero()); - - // send some tokens to create an escrow - let arb = Addr::unchecked("arbiter"); - let ben = String::from("beneficiary"); - let id = "demo".to_string(); - let create_msg = ReceiveMsg::Create(CreateMsg { - id: id.clone(), - arbiter: arb.to_string(), - recipient: ben.clone(), - end_height: None, - end_time: None, - cw20_whitelist: None, - }); - let send_msg = Cw20ExecuteMsg::Send { - contract: escrow_addr.to_string(), - amount: Uint128::new(1200), - msg: to_binary(&create_msg).unwrap(), - }; - let res = router - .execute_contract(owner.clone(), cash_addr.clone(), &send_msg, &[]) - .unwrap(); - assert_eq!(4, res.events.len()); - println!("{:?}", res.events); - - assert_eq!(res.events[0].ty.as_str(), "execute"); - let cw20_attr = res.custom_attrs(1); - println!("{:?}", cw20_attr); - assert_eq!(4, cw20_attr.len()); - - assert_eq!(res.events[2].ty.as_str(), "execute"); - let escrow_attr = res.custom_attrs(3); - println!("{:?}", escrow_attr); - assert_eq!(2, escrow_attr.len()); - - // ensure balances updated - let owner_balance = cash.balance(&router, owner.clone()).unwrap(); - assert_eq!(owner_balance, Uint128::new(3800)); - let escrow_balance = cash.balance(&router, escrow_addr.clone()).unwrap(); - assert_eq!(escrow_balance, Uint128::new(1200)); - - // ensure escrow properly created - let details: DetailsResponse = router - .wrap() - .query_wasm_smart(&escrow_addr, &QueryMsg::Details { id: id.clone() }) - .unwrap(); - assert_eq!(id, details.id); - assert_eq!(arb, details.arbiter); - assert_eq!(ben, details.recipient); - assert_eq!( - vec![Cw20Coin { - address: cash_addr.to_string(), - amount: Uint128::new(1200) - }], - details.cw20_balance - ); - - // release escrow - let approve_msg = ExecuteMsg::Approve { id }; - let _ = router - .execute_contract(arb, escrow_addr.clone(), &approve_msg, &[]) - .unwrap(); - - // ensure balances updated - release to ben - let owner_balance = cash.balance(&router, owner).unwrap(); - assert_eq!(owner_balance, Uint128::new(3800)); - let escrow_balance = cash.balance(&router, escrow_addr).unwrap(); - assert_eq!(escrow_balance, Uint128::zero()); - let ben_balance = cash.balance(&router, ben).unwrap(); - assert_eq!(ben_balance, Uint128::new(1200)); -} diff --git a/contracts/cw20-escrow/src/lib.rs b/contracts/cw20-escrow/src/lib.rs deleted file mode 100644 index 32ed6c387..000000000 --- a/contracts/cw20-escrow/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod contract; -mod error; -mod integration_test; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/contracts/cw20-escrow/src/msg.rs b/contracts/cw20-escrow/src/msg.rs deleted file mode 100644 index 8dbd607ea..000000000 --- a/contracts/cw20-escrow/src/msg.rs +++ /dev/null @@ -1,123 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Addr, Api, Coin, StdResult}; - -use cw20::{Cw20Coin, Cw20ReceiveMsg}; - -#[derive(Serialize, Deserialize, JsonSchema)] -pub struct InstantiateMsg {} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - Create(CreateMsg), - /// Adds all sent native tokens to the contract - TopUp { - id: String, - }, - /// Approve sends all tokens to the recipient. - /// Only the arbiter can do this - Approve { - /// id is a human-readable name for the escrow from create - id: String, - }, - /// Refund returns all remaining tokens to the original sender, - /// The arbiter can do this any time, or anyone can do this after a timeout - Refund { - /// id is a human-readable name for the escrow from create - id: String, - }, - /// This accepts a properly-encoded ReceiveMsg from a cw20 contract - Receive(Cw20ReceiveMsg), -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ReceiveMsg { - Create(CreateMsg), - /// Adds all sent native tokens to the contract - TopUp { - id: String, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct CreateMsg { - /// id is a human-readable name for the escrow to use later - /// 3-20 bytes of utf-8 text - pub id: String, - /// arbiter can decide to approve or refund the escrow - pub arbiter: String, - /// if approved, funds go to the recipient - pub recipient: String, - /// When end height set and block height exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_height: Option, - /// When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and - /// block time exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_time: Option, - /// Besides any possible tokens sent with the CreateMsg, this is a list of all cw20 token addresses - /// that are accepted by the escrow during a top-up. This is required to avoid a DoS attack by topping-up - /// with an invalid cw20 contract. See https://github.com/CosmWasm/cosmwasm-plus/issues/19 - pub cw20_whitelist: Option>, -} - -impl CreateMsg { - pub fn addr_whitelist(&self, api: &dyn Api) -> StdResult> { - match self.cw20_whitelist.as_ref() { - Some(v) => v.iter().map(|h| api.addr_validate(h)).collect(), - None => Ok(vec![]), - } - } -} - -pub fn is_valid_name(name: &str) -> bool { - let bytes = name.as_bytes(); - if bytes.len() < 3 || bytes.len() > 20 { - return false; - } - true -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Show all open escrows. Return type is ListResponse. - List {}, - /// Returns the details of the named escrow, error if not created - /// Return type: DetailsResponse. - Details { id: String }, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct ListResponse { - /// list all registered ids - pub escrows: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct DetailsResponse { - /// id of this escrow - pub id: String, - /// arbiter can decide to approve or refund the escrow - pub arbiter: String, - /// if approved, funds go to the recipient - pub recipient: String, - /// if refunded, funds go to the source - pub source: String, - /// When end height set and block height exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_height: Option, - /// When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and - /// block time exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_time: Option, - /// Balance in native tokens - pub native_balance: Vec, - /// Balance in cw20 tokens - pub cw20_balance: Vec, - /// Whitelisted cw20 tokens - pub cw20_whitelist: Vec, -} diff --git a/contracts/cw20-escrow/src/state.rs b/contracts/cw20-escrow/src/state.rs deleted file mode 100644 index 3940d6160..000000000 --- a/contracts/cw20-escrow/src/state.rs +++ /dev/null @@ -1,145 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Addr, Coin, Env, Order, StdResult, Storage, Timestamp}; -use cw_storage_plus::Map; - -use cw20::{Balance, Cw20CoinVerified}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] -pub struct GenericBalance { - pub native: Vec, - pub cw20: Vec, -} - -impl GenericBalance { - pub fn add_tokens(&mut self, add: Balance) { - match add { - Balance::Native(balance) => { - for token in balance.0 { - let index = self.native.iter().enumerate().find_map(|(i, exist)| { - if exist.denom == token.denom { - Some(i) - } else { - None - } - }); - match index { - Some(idx) => self.native[idx].amount += token.amount, - None => self.native.push(token), - } - } - } - Balance::Cw20(token) => { - let index = self.cw20.iter().enumerate().find_map(|(i, exist)| { - if exist.address == token.address { - Some(i) - } else { - None - } - }); - match index { - Some(idx) => self.cw20[idx].amount += token.amount, - None => self.cw20.push(token), - } - } - }; - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Escrow { - /// arbiter can decide to approve or refund the escrow - pub arbiter: Addr, - /// if approved, funds go to the recipient - pub recipient: Addr, - /// if refunded, funds go to the source - pub source: Addr, - /// When end height set and block height exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_height: Option, - /// When end time (in seconds since epoch 00:00:00 UTC on 1 January 1970) is set and - /// block time exceeds this value, the escrow is expired. - /// Once an escrow is expired, it can be returned to the original funder (via "refund"). - pub end_time: Option, - /// Balance in Native and Cw20 tokens - pub balance: GenericBalance, - /// All possible contracts that we accept tokens from - pub cw20_whitelist: Vec, -} - -impl Escrow { - pub fn is_expired(&self, env: &Env) -> bool { - if let Some(end_height) = self.end_height { - if env.block.height > end_height { - return true; - } - } - - if let Some(end_time) = self.end_time { - if env.block.time > Timestamp::from_seconds(end_time) { - return true; - } - } - - false - } - - pub fn human_whitelist(&self) -> Vec { - self.cw20_whitelist.iter().map(|a| a.to_string()).collect() - } -} - -pub const ESCROWS: Map<&str, Escrow> = Map::new("escrow"); - -/// This returns the list of ids for all registered escrows -pub fn all_escrow_ids(storage: &dyn Storage) -> StdResult> { - ESCROWS - .keys(storage, None, None, Order::Ascending) - .collect() -} - -#[cfg(test)] -mod tests { - use super::*; - - use cosmwasm_std::testing::MockStorage; - - #[test] - fn no_escrow_ids() { - let storage = MockStorage::new(); - let ids = all_escrow_ids(&storage).unwrap(); - assert_eq!(0, ids.len()); - } - - fn dummy_escrow() -> Escrow { - Escrow { - arbiter: Addr::unchecked("arb"), - recipient: Addr::unchecked("recip"), - source: Addr::unchecked("source"), - end_height: None, - end_time: None, - balance: Default::default(), - cw20_whitelist: vec![], - } - } - - #[test] - fn all_escrow_ids_in_order() { - let mut storage = MockStorage::new(); - ESCROWS - .save(&mut storage, &"lazy", &dummy_escrow()) - .unwrap(); - ESCROWS - .save(&mut storage, &"assign", &dummy_escrow()) - .unwrap(); - ESCROWS.save(&mut storage, &"zen", &dummy_escrow()).unwrap(); - - let ids = all_escrow_ids(&storage).unwrap(); - assert_eq!(3, ids.len()); - assert_eq!( - vec!["assign".to_string(), "lazy".to_string(), "zen".to_string()], - ids - ) - } -} diff --git a/contracts/cw20-merkle-airdrop/.cargo/config b/contracts/cw20-merkle-airdrop/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/contracts/cw20-merkle-airdrop/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/contracts/cw20-merkle-airdrop/Cargo.toml b/contracts/cw20-merkle-airdrop/Cargo.toml deleted file mode 100644 index fa64e4f28..000000000 --- a/contracts/cw20-merkle-airdrop/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "cw20-merkle-airdrop" -version = "0.7.0" -authors = ["Orkun Kulce ", "Terraform Labs, PTE."] -edition = "2018" -description = "An Airdrop contract for allowing users to claim rewards with Merkle Tree based proof" -license = "Apache-2.0" - -exclude = [ - "contract.wasm", - "hash.txt", -] - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cosmwasm-std = { version = "1.0.0-beta3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } -hex = "0.4" -sha2 = { version = "0.9.5", default-features = false } - -[dev-dependencies] -cosmwasm-schema = "1.0.0-beta3" -serde_json = "1.0" diff --git a/contracts/cw20-merkle-airdrop/NOTICE b/contracts/cw20-merkle-airdrop/NOTICE deleted file mode 100644 index 0f5ee7638..000000000 --- a/contracts/cw20-merkle-airdrop/NOTICE +++ /dev/null @@ -1,16 +0,0 @@ -CW20-Merkle-Airdrop: A reference implementation for merkle airdrop on CosmWasm - -Copyright (C) 2021 Terraform Labs, PTE. -Copyright (C) 2021 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-merkle-airdrop/README.md b/contracts/cw20-merkle-airdrop/README.md deleted file mode 100644 index a313d0043..000000000 --- a/contracts/cw20-merkle-airdrop/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# CW20 Merkle Airdrop - -This is a merkle airdrop smart contract that works with cw20 token specification Mass airdrop distributions made cheap -and efficient. - -Explanation of merkle -airdrop: [Medium Merkle Airdrop: the Basics](https://medium.com/smartz-blog/merkle-airdrop-the-basics-9a0857fcc930) - -Traditional and non-efficient airdrops: - -- Distributor creates a list of airdrop -- Sends bank send messages to send tokens to recipients - -**Or** - -- Stores list of recipients on smart contract data -- Recipient claims the airdrop - -These two solutions are very ineffective when recipient list is big. First, costly because bank send cost for the -distributor will be costly. Second, whole airdrop list stored in the state, again costly. - -Merkle Airdrop is very efficient even when recipient number is massive. - -This contract works with multiple airdrop rounds, meaning you can execute several airdrops using same instance. - -Uses **SHA256** for merkle root tree construction. - -## Procedure - -- Distributor of contract prepares a list of addresses with many entries and publishes this list in public static .js - file in JSON format -- Distributor reads this list, builds the merkle tree structure and writes down the Merkle root of it. -- Distributor creates contract and places calculated Merkle root into it. -- Distributor says to users, that they can claim their tokens, if they owe any of addresses, presented in list, - published on distributor's site. -- User wants to claim his N tokens, he also builds Merkle tree from public list and prepares Merkle proof, consisting - from log2N hashes, describing the way to reach Merkle root -- User sends transaction with Merkle proof to contract -- Contract checks Merkle proof, and, if proof is correct, then sender's address is in list of allowed addresses, and - contract does some action for this use. -- Distributor sends token to the contract, and registers new merkle root for the next distribution round. - -## Spec - -### Messages - -#### InstantiateMsg - -`InstantiateMsg` instantiates contract with owner and cw20 token address. Airdrop `stage` is set to 0. - -```rust -pub struct InstantiateMsg { - pub owner: String, - pub cw20_token_address: String, -} -``` - -#### ExecuteMsg - -```rust -pub enum ExecuteMsg { - UpdateConfig { - owner: Option, - }, - RegisterMerkleRoot { - merkle_root: String, - }, - Claim { - stage: u8, - amount: Uint128, - proof: Vec, - }, -} -``` - -- `UpdateConfig{owner}` updates configuration. -- `RegisterMerkleRoot {merkle_root}` registers merkle tree root for further claim verification. Airdrop `Stage` - increased by 1. -- `Claim{stage, amount, proof}` recipient executes for claiming airdrop with `stage`, `amount` and `proof` data built - using full list. - -#### QueryMsg - -``` rust -pub enum QueryMsg { - Config {}, - MerkleRoot { stage: u8 }, - LatestStage {}, - IsClaimed { stage: u8, address: String }, -} -``` - -- `{ config: {} }` returns configuration, `{"cw20_token_address": ..., "owner": ...}`. -- `{ merkle_root: { stage: "1" }` returns merkle root of given stage, `{"merkle_root": ... , "stage": ...}` -- `{ latest_stage: {}}` returns current airdrop stage, `{"latest_stage": ...}` -- `{ is_claimed: {stage: "stage", address: "wasm1..."}` returns if address claimed airdrop, `{"is_claimed": "true"}` - -## Merkle Airdrop CLI - -[Merkle Airdrop CLI](helpers) contains js helpers for generating root, generating and verifying proofs for given airdrop -file. - -## Test Vector Generation - -Test vector can be generated using commands at [Merkle Airdrop CLI README](helpers/README.md) diff --git a/contracts/cw20-merkle-airdrop/examples/schema.rs b/contracts/cw20-merkle-airdrop/examples/schema.rs deleted file mode 100644 index d3725a5f8..000000000 --- a/contracts/cw20-merkle-airdrop/examples/schema.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use cw20_merkle_airdrop::msg::{ - ConfigResponse, ExecuteMsg, InstantiateMsg, IsClaimedResponse, LatestStageResponse, - MerkleRootResponse, QueryMsg, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(LatestStageResponse), &out_dir); - export_schema(&schema_for!(MerkleRootResponse), &out_dir); - export_schema(&schema_for!(IsClaimedResponse), &out_dir); - export_schema(&schema_for!(ConfigResponse), &out_dir); -} diff --git a/contracts/cw20-merkle-airdrop/helpers/.eslintignore b/contracts/cw20-merkle-airdrop/helpers/.eslintignore deleted file mode 100644 index 502167fa0..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -/lib diff --git a/contracts/cw20-merkle-airdrop/helpers/.eslintrc b/contracts/cw20-merkle-airdrop/helpers/.eslintrc deleted file mode 100644 index 7b846193c..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": [ - "oclif", - "oclif-typescript" - ] -} diff --git a/contracts/cw20-merkle-airdrop/helpers/.gitignore b/contracts/cw20-merkle-airdrop/helpers/.gitignore deleted file mode 100644 index 9d6ea2ca5..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*-debug.log -*-error.log -/.nyc_output -/dist -/lib -/package-lock.json -/tmp -node_modules diff --git a/contracts/cw20-merkle-airdrop/helpers/README.md b/contracts/cw20-merkle-airdrop/helpers/README.md deleted file mode 100644 index c9e4a9760..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/README.md +++ /dev/null @@ -1,47 +0,0 @@ -merkle-airdrop-cli -================== - -This is a helper client shipped along contract. -Use this to generate root, generate proofs and verify proofs - -## Installation - -```shell -yarn install -yarn link -``` - -Binary will be placed to path. - -## Airdrop file format - -```json -[ - { "address": "wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq", "amount": "100"}, - { "address": "wasm1uy9ucvgerneekxpnfwyfnpxvlsx5dzdpf0mzjd", "amount": "1010"} -] -``` - -## Commands - -**Generate Root:** -```shell -merkle-airdrop-cli generateRoot --file ../testdata/airdrop_stage_2_list.json -``` - -**Generate proof:** -```shell -merkle-airdrop-cli generateProofs --file ../testdata/airdrop_stage_2_list.json \ - --address wasm1ylna88nach9sn5n7qe7u5l6lh7dmt6lp2y63xx \ - --amount 1000000000 -``` - -**Verify proof:** -```shell -PROOFS='[ "27e9b1ec8cb64709d0a8d3702344561674199fe81b885f1f9c9b2fb268795962","280777995d054081cbf208bccb70f8d736c1766b81d90a1fd21cd97d2d83a5cc","3946ea1758a5a2bf55bae1186168ad35aa0329805bc8bff1ca3d51345faec04a" -]' -merkle-airdrop-cli verifyProofs --file ../testdata/airdrop.json \ - --address wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq \ - --amount 100 \ - --proofs $PROOFS -``` diff --git a/contracts/cw20-merkle-airdrop/helpers/bin/run b/contracts/cw20-merkle-airdrop/helpers/bin/run deleted file mode 100755 index 30b14e177..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/bin/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env node - -require('@oclif/command').run() -.then(require('@oclif/command/flush')) -.catch(require('@oclif/errors/handle')) diff --git a/contracts/cw20-merkle-airdrop/helpers/bin/run.cmd b/contracts/cw20-merkle-airdrop/helpers/bin/run.cmd deleted file mode 100644 index 968fc3075..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/bin/run.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -node "%~dp0\run" %* diff --git a/contracts/cw20-merkle-airdrop/helpers/package.json b/contracts/cw20-merkle-airdrop/helpers/package.json deleted file mode 100644 index 8e249ee3b..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "merkle-airdrop-cli", - "version": "0.1.0", - "author": "Orkun Külçe @orkunkl", - "bin": { - "merkle-airdrop-cli": "./bin/run" - }, - "dependencies": { - "@cosmjs/crypto": "^0.25.5", - "@cosmjs/encoding": "^0.25.5", - "@oclif/command": "^1", - "@oclif/config": "^1", - "@oclif/plugin-help": "^3", - "@types/crypto-js": "^4.0.2", - "ethereumjs-util": "^7.1.0", - "merkletreejs": "^0.2.23", - "tslib": "^1" - }, - "devDependencies": { - "@oclif/dev-cli": "^1", - "@types/node": "^10", - "eslint": "^5.13", - "eslint-config-oclif": "^3.1", - "eslint-config-oclif-typescript": "^0.1", - "globby": "^10", - "ts-node": "^8", - "typescript": "^3.3" - }, - "engines": { - "node": ">=8.0.0" - }, - "files": [ - "/bin", - "/lib", - "/npm-shrinkwrap.json", - "/oclif.manifest.json" - ], - "keywords": [ - "cosmwasm", - "cw20" - ], - "license": "Apache-2.0", - "main": "lib/index.js", - "oclif": { - "commands": "./lib/commands", - "bin": "merkle-airdrop-cli", - "plugins": [ - "@oclif/plugin-help" - ] - }, - "repository": "CosmWasm/cosmwasm-plus/cw20-merkle-airdrop/merkle-airdrop-cli", - "scripts": { - "postpack": "rm -f oclif.manifest.json", - "posttest": "eslint . --ext .ts --config .eslintrc", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", - "test": "echo NO TESTS", - "version": "oclif-dev readme && git add README.md" - }, - "types": "lib/index.d.ts" -} diff --git a/contracts/cw20-merkle-airdrop/helpers/src/airdrop.ts b/contracts/cw20-merkle-airdrop/helpers/src/airdrop.ts deleted file mode 100644 index 87972b047..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/src/airdrop.ts +++ /dev/null @@ -1,44 +0,0 @@ -import sha256 from 'crypto-js/sha256' -import { MerkleTree } from 'merkletreejs'; - -class Airdrop { - private tree: MerkleTree; - - constructor(accounts: Array<{ address: string; amount: string }>) { - const leaves = accounts.map((a) => sha256(a.address + a.amount)); - this.tree = new MerkleTree(leaves, sha256, { sort: true }); - } - - public getMerkleRoot(): string { - return this.tree.getHexRoot().replace('0x', ''); - } - - public getMerkleProof(account: { - address: string; - amount: string; - }): string[] { - return this.tree - .getHexProof(sha256(account.address + account.amount).toString()) - .map((v) => v.replace('0x', '')); - } - - public verify( - proof: string[], - account: { address: string; amount: string } - ): boolean { - let hashBuf = Buffer.from(sha256(account.address + account.amount).toString()) - - proof.forEach((proofElem) => { - const proofBuf = Buffer.from(proofElem, 'hex'); - if (hashBuf < proofBuf) { - hashBuf = Buffer.from(sha256(Buffer.concat([hashBuf, proofBuf]).toString())); - } else { - hashBuf = Buffer.from(sha256(Buffer.concat([proofBuf, hashBuf]).toString())); - } - }); - - return this.getMerkleRoot() === hashBuf.toString('hex'); - } -} - -export {Airdrop} diff --git a/contracts/cw20-merkle-airdrop/helpers/src/commands/generateProofs.ts b/contracts/cw20-merkle-airdrop/helpers/src/commands/generateProofs.ts deleted file mode 100644 index 6181e1d9b..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/src/commands/generateProofs.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Command, flags} from '@oclif/command' -import { readFileSync } from 'fs'; -import {Airdrop} from '../airdrop'; - -export default class GenerateProof extends Command { - static description = 'Generates merkle proofs for given address' - - static examples = [ - `$ merkle-airdrop-cli generateProofs --file ../testdata/airdrop_stage_2.json \ - --address wasm1ylna88nach9sn5n7qe7u5l6lh7dmt6lp2y63xx \ - --amount 1000000000 -`, - ] - - static flags = { - help: flags.help({char: 'h'}), - file: flags.string({char: 'f', description: 'airdrop file location'}), - address: flags.string({char: 'a', description: 'address'}), - amount: flags.string({char: 'b', description: 'amount'}), - } - - async run() { - const {flags} = this.parse(GenerateProof) - - if (!flags.file) { - this.error(new Error('Airdrop file location not defined')) - } - if (!flags.address) { - this.error(new Error('Address not defined')) - } - if (!flags.amount) { - this.error(new Error('Amount not defined')) - } - - let file; - try { - file = readFileSync(flags.file, 'utf-8'); - } catch (e) { - this.error(e) - } - - let receivers: Array<{ address: string; amount: string }> = JSON.parse(file); - - let airdrop = new Airdrop(receivers) - let proof = airdrop.getMerkleProof({address: flags.address, amount: flags.amount}) - console.log(proof) - } -} diff --git a/contracts/cw20-merkle-airdrop/helpers/src/commands/generateRoot.ts b/contracts/cw20-merkle-airdrop/helpers/src/commands/generateRoot.ts deleted file mode 100644 index a8875fe04..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/src/commands/generateRoot.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Command, flags} from '@oclif/command' -import { readFileSync } from 'fs'; -import {Airdrop} from '../airdrop'; - -export default class GenerateRoot extends Command { - static description = 'Generates merkle root' - - static examples = [ - `$ merkle-airdrop-cli generateRoot --file ../testdata/airdrop_stage_2.json -`, - ] - - static flags = { - help: flags.help({char: 'h'}), - file: flags.string({char: 'f', description: 'Airdrop file location'}), - } - - async run() { - const {flags} = this.parse(GenerateRoot) - - if (!flags.file) { - this.error(new Error('Airdrop file location not defined')) - } - - let file; - try { - file = readFileSync(flags.file, 'utf-8'); - } catch (e) { - this.error(e) - } - - let receivers: Array<{ address: string; amount: string }> = JSON.parse(file); - - let airdrop = new Airdrop(receivers) - console.log(airdrop.getMerkleRoot()) - } -} diff --git a/contracts/cw20-merkle-airdrop/helpers/src/commands/verifyProofs.ts b/contracts/cw20-merkle-airdrop/helpers/src/commands/verifyProofs.ts deleted file mode 100644 index 3915ae45f..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/src/commands/verifyProofs.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {Command, flags} from '@oclif/command' -import { readFileSync } from 'fs'; -import {Airdrop} from '../airdrop'; - -export default class VerifyProof extends Command { - static description = 'Verifies merkle proofs for given address' - - static examples = [ - `$ PROOFS='[ "27e9b1ec8cb64709d0a8d3702344561674199fe81b885f1f9c9b2fb268795962","280777995d054081cbf208bccb70f8d736c1766b81d90a1fd21cd97d2d83a5cc","3946ea1758a5a2bf55bae1186168ad35aa0329805bc8bff1ca3d51345faec04a"]' - $ merkle-airdrop-cli verifyProofs --file ../testdata/airdrop.json \ - --address wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq \ - --amount 100 - --proofs $PROOFS -`, - ] - - static flags = { - help: flags.help({char: 'h'}), - file: flags.string({char: 'f', description: 'airdrop file location'}), - proofs: flags.string({char: 'p', description: 'proofs in json format'}), - address: flags.string({char: 'a', description: 'address'}), - amount: flags.string({char: 'b', description: 'amount'}), - } - - async run() { - const {flags} = this.parse(VerifyProof) - - if (!flags.file) { - this.error(new Error('Airdrop file location not defined')) - } - if (!flags.proofs) { - this.error(new Error('Proofs not defined')) - } - if (!flags.address) { - this.error(new Error('Address not defined')) - } - if (!flags.amount) { - this.error(new Error('Amount not defined')) - } - - let file; - try { - file = readFileSync(flags.file, 'utf-8'); - } catch (e) { - this.error(e) - } - - let receivers: Array<{ address: string; amount: string }> = JSON.parse(file); - - let airdrop = new Airdrop(receivers) - let proofs: string[] = JSON.parse(flags.proofs) - - console.log(airdrop.verify(proofs, {address: flags.address, amount: flags.amount})) - } -} diff --git a/contracts/cw20-merkle-airdrop/helpers/src/index.ts b/contracts/cw20-merkle-airdrop/helpers/src/index.ts deleted file mode 100644 index 4caa481ee..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {run} from '@oclif/command' diff --git a/contracts/cw20-merkle-airdrop/helpers/tsconfig.json b/contracts/cw20-merkle-airdrop/helpers/tsconfig.json deleted file mode 100644 index 8964312f8..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "importHelpers": true, - "outDir": "lib", - "rootDir": "src", - "strict": true, - "target": "es2017", - "allowSyntheticDefaultImports": true, - "alwaysStrict": true, - "baseUrl": "./", - "declaration": true, - "esModuleInterop": true, - "lib": ["es2015", "es2016", "es2017", "dom"], - "module": "commonjs", - "moduleResolution": "node", - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noUnusedLocals": false, - "noUnusedParameters": true, - "sourceMap": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "paths": { - "*": ["src/*"] - } - }, - "include": [ - "src/**/*" - ] -} diff --git a/contracts/cw20-merkle-airdrop/helpers/yarn.lock b/contracts/cw20-merkle-airdrop/helpers/yarn.lock deleted file mode 100644 index a07471937..000000000 --- a/contracts/cw20-merkle-airdrop/helpers/yarn.lock +++ /dev/null @@ -1,2767 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" - integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@cosmjs/crypto@^0.25.5": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.25.6.tgz#695d2d0d2195bdbdd5825d415385646244900bbb" - integrity sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw== - dependencies: - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - bip39 "^3.0.2" - bn.js "^4.11.8" - elliptic "^6.5.3" - js-sha3 "^0.8.0" - libsodium-wrappers "^0.7.6" - ripemd160 "^2.0.2" - sha.js "^2.4.11" - -"@cosmjs/encoding@^0.25.5", "@cosmjs/encoding@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" - integrity sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - readonly-date "^1.0.0" - -"@cosmjs/math@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.25.6.tgz#25c7b106aaded889a5b80784693caa9e654b0c28" - integrity sha512-Fmyc9FJ8KMU34n7rdapMJrT/8rx5WhMw2F7WLBu7AVLcBh0yWsXIcMSJCoPHTOnMIiABjXsnrrwEaLrOOBfu6A== - dependencies: - bn.js "^4.11.8" - -"@cosmjs/utils@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" - integrity sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@oclif/command@^1", "@oclif/command@^1.5.20", "@oclif/command@^1.6.0", "@oclif/command@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.0.tgz#c1a499b10d26e9d1a611190a81005589accbb339" - integrity sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw== - dependencies: - "@oclif/config" "^1.15.1" - "@oclif/errors" "^1.3.3" - "@oclif/parser" "^3.8.3" - "@oclif/plugin-help" "^3" - debug "^4.1.1" - semver "^7.3.2" - -"@oclif/config@^1", "@oclif/config@^1.15.1", "@oclif/config@^1.17.0": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.17.0.tgz#ba8639118633102a7e481760c50054623d09fcab" - integrity sha512-Lmfuf6ubjQ4ifC/9bz1fSCHc6F6E653oyaRXxg+lgT4+bYf9bk+nqrUpAbrXyABkCqgIBiFr3J4zR/kiFdE1PA== - dependencies: - "@oclif/errors" "^1.3.3" - "@oclif/parser" "^3.8.0" - debug "^4.1.1" - globby "^11.0.1" - is-wsl "^2.1.1" - tslib "^2.0.0" - -"@oclif/dev-cli@^1": - version "1.26.0" - resolved "https://registry.yarnpkg.com/@oclif/dev-cli/-/dev-cli-1.26.0.tgz#e3ec294b362c010ffc8948003d3770955c7951fd" - integrity sha512-272udZP+bG4qahoAcpWcMTJKiA+V42kRMqQM7n4tgW35brYb2UP5kK+p08PpF8sgSfRTV8MoJVJG9ax5kY82PA== - dependencies: - "@oclif/command" "^1.8.0" - "@oclif/config" "^1.17.0" - "@oclif/errors" "^1.3.3" - "@oclif/plugin-help" "^3.2.0" - cli-ux "^5.2.1" - debug "^4.1.1" - find-yarn-workspace-root "^2.0.0" - fs-extra "^8.1" - github-slugger "^1.2.1" - lodash "^4.17.11" - normalize-package-data "^3.0.0" - qqjs "^0.3.10" - tslib "^2.0.3" - -"@oclif/errors@^1.2.1", "@oclif/errors@^1.2.2", "@oclif/errors@^1.3.3": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@oclif/errors/-/errors-1.3.5.tgz#a1e9694dbeccab10fe2fe15acb7113991bed636c" - integrity sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ== - dependencies: - clean-stack "^3.0.0" - fs-extra "^8.1" - indent-string "^4.0.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -"@oclif/linewrap@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" - integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== - -"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3": - version "3.8.5" - resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.5.tgz#c5161766a1efca7343e1f25d769efbefe09f639b" - integrity sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg== - dependencies: - "@oclif/errors" "^1.2.2" - "@oclif/linewrap" "^1.0.0" - chalk "^2.4.2" - tslib "^1.9.3" - -"@oclif/plugin-help@^3", "@oclif/plugin-help@^3.2.0": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-3.2.2.tgz#063ee08cee556573a5198fbdfdaa32796deba0ed" - integrity sha512-SPZ8U8PBYK0n4srFjCLedk0jWU4QlxgEYLCXIBShJgOwPhTTQknkUlsEwaMIevvCU4iCQZhfMX+D8Pz5GZjFgA== - dependencies: - "@oclif/command" "^1.5.20" - "@oclif/config" "^1.15.1" - "@oclif/errors" "^1.2.2" - chalk "^4.1.0" - indent-string "^4.0.0" - lodash.template "^4.4.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - widest-line "^3.1.0" - wrap-ansi "^4.0.0" - -"@oclif/screen@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" - integrity sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw== - -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/crypto-js@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.0.2.tgz#4524325a175bf819fec6e42560c389ce1fb92c97" - integrity sha512-sCVniU+h3GcGqxOmng11BRvf9TfN9yIs8KKjB8C8d75W69cpTfZG80gau9yTx5SxF3gvHGbJhdESzzvnjtf3Og== - -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== - -"@types/glob@^7.1.1": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" - integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.3": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/node@*": - version "16.4.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.11.tgz#245030af802c776c31f00eb0cdde40ee615db462" - integrity sha512-nWSFUbuNiPKJEe1IViuodSI+9cM+vpM8SWF/O6dJK7wmGRNq55U7XavJHrlRrPkSMuUZUFzg1xaZ1B+ZZCrRWw== - -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - -"@types/node@^10": - version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" - integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@typescript-eslint/eslint-plugin@^2.6.1": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" - integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== - dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" - functional-red-black-tree "^1.0.1" - regexpp "^3.0.0" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" - integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@^2.6.1": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" - integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== - dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-visitor-keys "^1.1.0" - -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" - integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== - dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" - -acorn-jsx@^5.0.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^6.0.7: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -ajv@^6.10.2, ajv@^6.9.1: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.0, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bech32@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -bignumber.js@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -bip39@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" - integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -blakejs@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" - integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-reverse@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-reverse/-/buffer-reverse-1.0.1.tgz#49283c8efa6f901bc01fa3304d06027971ae2f60" - integrity sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A= - -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -cardinal@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" - integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU= - dependencies: - ansicolors "~0.3.2" - redeyed "~2.1.0" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -clean-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" - integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= - dependencies: - escape-string-regexp "^1.0.5" - -clean-stack@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-3.0.1.tgz#155bf0b2221bf5f4fba89528d24c5953f17fe3a8" - integrity sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg== - dependencies: - escape-string-regexp "4.0.0" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-progress@^3.4.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.9.0.tgz#25db83447deb812e62d05bac1af9aec5387ef3d4" - integrity sha512-g7rLWfhAo/7pF+a/STFH/xPyosaL1zgADhI0OM83hl3c7S43iGvJWEAV2QuDOnQ8i6EMBj/u4+NTd0d5L+4JfA== - dependencies: - colors "^1.1.2" - string-width "^4.2.0" - -cli-ux@^5.2.1: - version "5.6.3" - resolved "https://registry.yarnpkg.com/cli-ux/-/cli-ux-5.6.3.tgz#eecdb2e0261171f2b28f2be6b18c490291c3a287" - integrity sha512-/oDU4v8BiDjX2OKcSunGH0iGDiEtj2rZaGyqNuv9IT4CgcSMyVWAMfn0+rEHaOc4n9ka78B0wo1+N1QX89f7mw== - dependencies: - "@oclif/command" "^1.6.0" - "@oclif/errors" "^1.2.1" - "@oclif/linewrap" "^1.0.0" - "@oclif/screen" "^1.0.3" - ansi-escapes "^4.3.0" - ansi-styles "^4.2.0" - cardinal "^2.1.1" - chalk "^4.1.0" - clean-stack "^3.0.0" - cli-progress "^3.4.0" - extract-stack "^2.0.0" - fs-extra "^8.1" - hyperlinker "^1.0.0" - indent-string "^4.0.0" - is-wsl "^2.2.0" - js-yaml "^3.13.1" - lodash "^4.17.11" - natural-orderby "^2.0.1" - object-treeify "^1.1.4" - password-prompt "^1.1.2" - semver "^7.3.2" - string-width "^4.2.0" - strip-ansi "^6.0.0" - supports-color "^8.1.0" - supports-hyperlinks "^2.1.0" - tslib "^2.0.0" - -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -content-type@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-js@^3.1.9-1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - -debug@^4.0.1, debug@^4.1.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -detect-indent@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" - integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -"emoji-regex@>=6.0.0 <=6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" - integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-ast-utils@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" - integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== - dependencies: - lodash.get "^4.4.2" - lodash.zip "^4.2.0" - -eslint-config-oclif-typescript@^0.1: - version "0.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-oclif-typescript/-/eslint-config-oclif-typescript-0.1.0.tgz#c310767c5ee8916ea5d08cf027d0317dd52ed8ba" - integrity sha512-BjXNJcH2F02MdaSFml9vJskviUFVkLHbTPGM5tinIt98H6klFNKP7/lQ+fB/Goc2wB45usEuuw6+l/fwAv9i7g== - dependencies: - "@typescript-eslint/eslint-plugin" "^2.6.1" - "@typescript-eslint/parser" "^2.6.1" - eslint-config-oclif "^3.1.0" - eslint-config-xo-space "^0.20.0" - eslint-plugin-mocha "^5.2.0" - eslint-plugin-node "^7.0.1" - eslint-plugin-unicorn "^6.0.1" - -eslint-config-oclif@^3.1, eslint-config-oclif@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-oclif/-/eslint-config-oclif-3.1.0.tgz#cbc207ced09e31676dcee2f724fc509cd20eb0bd" - integrity sha512-Tqgy43cNXsSdhTLWW4RuDYGFhV240sC4ISSv/ZiUEg/zFxExSEUpRE6J+AGnkKY9dYwIW4C9b2YSUVv8z/miMA== - dependencies: - eslint-config-xo-space "^0.20.0" - eslint-plugin-mocha "^5.2.0" - eslint-plugin-node "^7.0.1" - eslint-plugin-unicorn "^6.0.1" - -eslint-config-xo-space@^0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/eslint-config-xo-space/-/eslint-config-xo-space-0.20.0.tgz#75e1fb86d1b052fc1cc3036ca2fa441fa92b85e4" - integrity sha512-bOsoZA8M6v1HviDUIGVq1fLVnSu3mMZzn85m2tqKb73tSzu4GKD4Jd2Py4ZKjCgvCbRRByEB5HPC3fTMnnJ1uw== - dependencies: - eslint-config-xo "^0.24.0" - -eslint-config-xo@^0.24.0: - version "0.24.2" - resolved "https://registry.yarnpkg.com/eslint-config-xo/-/eslint-config-xo-0.24.2.tgz#f61b8ce692e9f9519bdb6edc4ed7ebcd5be48f48" - integrity sha512-ivQ7qISScW6gfBp+p31nQntz1rg34UCybd3uvlngcxt5Utsf4PMMi9QoAluLFcPUM5Tvqk4JGraR9qu3msKPKQ== - -eslint-plugin-es@^1.3.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998" - integrity sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA== - dependencies: - eslint-utils "^1.4.2" - regexpp "^2.0.1" - -eslint-plugin-mocha@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.3.0.tgz#cf3eb18ae0e44e433aef7159637095a7cb19b15b" - integrity sha512-3uwlJVLijjEmBeNyH60nzqgA1gacUWLUmcKV8PIGNvj1kwP/CTgAWQHn2ayyJVwziX+KETkr9opNwT1qD/RZ5A== - dependencies: - ramda "^0.26.1" - -eslint-plugin-node@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz#a6e054e50199b2edd85518b89b4e7b323c9f36db" - integrity sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw== - dependencies: - eslint-plugin-es "^1.3.1" - eslint-utils "^1.3.1" - ignore "^4.0.2" - minimatch "^3.0.4" - resolve "^1.8.1" - semver "^5.5.0" - -eslint-plugin-unicorn@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-6.0.1.tgz#4a97f0bc9449e20b82848dad12094ee2ba72347e" - integrity sha512-hjy9LhTdtL7pz8WTrzS0CGXRkWK3VAPLDjihofj8JC+uxQLfXm0WwZPPPB7xKmcjRyoH+jruPHOCrHNEINpG/Q== - dependencies: - clean-regexp "^1.0.0" - eslint-ast-utils "^1.0.0" - import-modules "^1.1.0" - lodash.camelcase "^4.1.1" - lodash.kebabcase "^4.0.1" - lodash.snakecase "^4.0.1" - lodash.upperfirst "^4.2.0" - safe-regex "^1.1.0" - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1, eslint-utils@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^5.13: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.1" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.11" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.2.3" - text-table "^0.2.0" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^4.0.0, esprima@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0, esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereumjs-util@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz#e2b43a30bfcdbcb432a4eb42bd5f2393209b3fd5" - integrity sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.4" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" - integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== - dependencies: - cross-spawn "^6.0.0" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extract-stack@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/extract-stack/-/extract-stack-2.0.0.tgz#11367bc865bfcd9bc0db3123e5edb57786f11f9b" - integrity sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ== - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.0.3, fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.1.tgz#5d8175aae17db61947f8b162cfc7f63264d22807" - integrity sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw== - dependencies: - reusify "^1.0.4" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-yarn-workspace-root@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" - integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== - dependencies: - micromatch "^4.0.2" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" - integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -github-slugger@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" - integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== - dependencies: - emoji-regex ">=6.0.0 <=6.1.1" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.2, glob@^7.1.3, glob@^7.1.6: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^11.7.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^10, globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hosted-git-info@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" - integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== - dependencies: - lru-cache "^6.0.0" - -http-call@^5.1.2: - version "5.3.0" - resolved "https://registry.yarnpkg.com/http-call/-/http-call-5.3.0.tgz#4ded815b13f423de176eb0942d69c43b25b148db" - integrity sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w== - dependencies: - content-type "^1.0.4" - debug "^4.1.1" - is-retry-allowed "^1.1.0" - is-stream "^2.0.0" - parse-json "^4.0.0" - tunnel-agent "^0.6.0" - -hyperlinker@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" - integrity sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ== - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.2, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" - integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-core-module@^2.2.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" - integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== - dependencies: - has "^1.0.3" - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - -is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-retry-allowed@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-wsl@^2.1.1, is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -keccak@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -libsodium-wrappers@^0.7.6: - version "0.7.9" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#4ffc2b69b8f7c7c7c5594a93a4803f80f6d0f346" - integrity sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ== - dependencies: - libsodium "^0.7.0" - -libsodium@^0.7.0: - version "0.7.9" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b" - integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A== - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" - integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== - dependencies: - graceful-fs "^4.1.15" - parse-json "^5.0.0" - strip-bom "^4.0.0" - type-fest "^0.6.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash.camelcase@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.kebabcase@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.snakecase@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= - -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.upperfirst@^4.2.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" - integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= - -lodash.zip@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" - integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= - -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -merge2@^1.2.3, merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merkletreejs@^0.2.23: - version "0.2.24" - resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.2.24.tgz#6dc52b3e0946846c25816216f1b60094a18a5e7a" - integrity sha512-JUv2zSFuTpMj9uxqNXAOAQz6LKXL/AUalyuDzvqyf0fV09VeU7WjNDMDD+wbdtrA1mNEbV5w1XDWXMud8aNYTg== - dependencies: - bignumber.js "^9.0.1" - buffer-reverse "^1.0.1" - crypto-js "^3.1.9-1" - treeify "^1.1.0" - web3-utils "^1.3.4" - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -natural-orderby@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/natural-orderby/-/natural-orderby-2.0.3.tgz#8623bc518ba162f8ff1cdb8941d74deb0fdcc016" - integrity sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-gyp-build@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== - -normalize-package-data@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.2.tgz#cae5c410ae2434f9a6c1baa65d5bc3b9366c8699" - integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg== - dependencies: - hosted-git-info "^4.0.1" - resolve "^1.20.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-treeify@^1.1.4: - version "1.1.33" - resolved "https://registry.yarnpkg.com/object-treeify/-/object-treeify-1.1.33.tgz#f06fece986830a3cba78ddd32d4c11d1f76cdf40" - integrity sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -optionator@^0.8.2: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -password-prompt@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" - integrity sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA== - dependencies: - ansi-escapes "^3.1.0" - cross-spawn "^6.0.5" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pbkdf2@^3.0.17, pbkdf2@^3.0.9: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qqjs@^0.3.10: - version "0.3.11" - resolved "https://registry.yarnpkg.com/qqjs/-/qqjs-0.3.11.tgz#795b9f7d00807d75c391b1241b5be3077143d9ea" - integrity sha512-pB2X5AduTl78J+xRSxQiEmga1jQV0j43jOPs/MTgTLApGFEOn6NgdE2dEjp7nvDtjkIOZbvFIojAiYUx6ep3zg== - dependencies: - chalk "^2.4.1" - debug "^4.1.1" - execa "^0.10.0" - fs-extra "^6.0.1" - get-stream "^5.1.0" - glob "^7.1.2" - globby "^10.0.1" - http-call "^5.1.2" - load-json-file "^6.2.0" - pkg-dir "^4.2.0" - tar-fs "^2.0.0" - tmp "^0.1.0" - write-json-file "^4.1.1" - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -ramda@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" - integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== - -randombytes@^2.0.1, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readonly-date@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" - integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== - -redeyed@~2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" - integrity sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= - dependencies: - esprima "~4.0.0" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpp@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.20.0, resolve@^1.8.1: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.4: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" - integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== - dependencies: - bn.js "^4.11.1" - -run-async@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^6.4.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -semver@^5.5.0, semver@^5.5.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.2, semver@^7.3.4: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -sort-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18" - integrity sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg== - dependencies: - is-plain-obj "^2.0.0" - -source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmp@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -treeify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" - integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== - -ts-node@^8: - version "8.10.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" - integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tslib@^1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0, tslib@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tsutils@^3.17.1: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@^3.3: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -web3-utils@^1.3.4: - version "1.5.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.5.0.tgz#48c8ba0d95694e73b9a6d473d955880cd4758e4a" - integrity sha512-hNyw7Oxi6TM3ivXmv4hK5Cvyi9ML3UoKtcCYvLF9woPWh5v2dwCCVO1U3Iq5HHK7Dqq28t1d4CxWHqUfOfAkgg== - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-4.0.0.tgz#b3570d7c70156159a2d42be5cc942e957f7b1131" - integrity sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg== - dependencies: - ansi-styles "^3.2.0" - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -write-json-file@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-4.3.0.tgz#908493d6fd23225344af324016e4ca8f702dd12d" - integrity sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ== - dependencies: - detect-indent "^6.0.0" - graceful-fs "^4.1.15" - is-plain-obj "^2.0.0" - make-dir "^3.0.0" - sort-keys "^4.0.0" - write-file-atomic "^3.0.0" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr@^2.0.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/contracts/cw20-merkle-airdrop/src/contract.rs b/contracts/cw20-merkle-airdrop/src/contract.rs deleted file mode 100644 index bdf555e84..000000000 --- a/contracts/cw20-merkle-airdrop/src/contract.rs +++ /dev/null @@ -1,548 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - attr, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, - WasmMsg, -}; -use cw2::{get_contract_version, set_contract_version}; -use cw20::Cw20ExecuteMsg; -use sha2::Digest; -use std::convert::TryInto; - -use crate::error::ContractError; -use crate::msg::{ - ConfigResponse, ExecuteMsg, InstantiateMsg, IsClaimedResponse, LatestStageResponse, - MerkleRootResponse, MigrateMsg, QueryMsg, -}; -use crate::state::{Config, CLAIM, CONFIG, LATEST_STAGE, MERKLE_ROOT}; - -// Version info, for migration info -const CONTRACT_NAME: &str = "crates.io:cw20-merkle-airdrop"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> StdResult { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - let owner = msg - .owner - .map_or(Ok(info.sender), |o| deps.api.addr_validate(&o))?; - - let config = Config { - owner: Some(owner), - cw20_token_address: deps.api.addr_validate(&msg.cw20_token_address)?, - }; - CONFIG.save(deps.storage, &config)?; - - let stage = 0; - LATEST_STAGE.save(deps.storage, &stage)?; - - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::UpdateConfig { new_owner } => execute_update_config(deps, env, info, new_owner), - ExecuteMsg::RegisterMerkleRoot { merkle_root } => { - execute_register_merkle_root(deps, env, info, merkle_root) - } - ExecuteMsg::Claim { - stage, - amount, - proof, - } => execute_claim(deps, env, info, stage, amount, proof), - } -} - -pub fn execute_update_config( - deps: DepsMut, - _env: Env, - info: MessageInfo, - new_owner: Option, -) -> Result { - // authorize owner - let cfg = CONFIG.load(deps.storage)?; - let owner = cfg.owner.ok_or(ContractError::Unauthorized {})?; - if info.sender != owner { - return Err(ContractError::Unauthorized {}); - } - - // if owner some validated to addr, otherwise set to none - let mut tmp_owner = None; - if let Some(addr) = new_owner { - tmp_owner = Some(deps.api.addr_validate(&addr)?) - } - - CONFIG.update(deps.storage, |mut exists| -> StdResult<_> { - exists.owner = tmp_owner; - Ok(exists) - })?; - - Ok(Response::new().add_attribute("action", "update_config")) -} - -pub fn execute_register_merkle_root( - deps: DepsMut, - _env: Env, - info: MessageInfo, - merkle_root: String, -) -> Result { - let cfg = CONFIG.load(deps.storage)?; - - // if owner set validate, otherwise unauthorized - let owner = cfg.owner.ok_or(ContractError::Unauthorized {})?; - if info.sender != owner { - return Err(ContractError::Unauthorized {}); - } - - // check merkle root length - let mut root_buf: [u8; 32] = [0; 32]; - hex::decode_to_slice(merkle_root.to_string(), &mut root_buf)?; - - let stage = LATEST_STAGE.update(deps.storage, |stage| -> StdResult<_> { Ok(stage + 1) })?; - - MERKLE_ROOT.save(deps.storage, stage, &merkle_root)?; - LATEST_STAGE.save(deps.storage, &stage)?; - - Ok(Response::new().add_attributes(vec![ - attr("action", "register_merkle_root"), - attr("stage", stage.to_string()), - attr("merkle_root", merkle_root), - ])) -} - -pub fn execute_claim( - deps: DepsMut, - _env: Env, - info: MessageInfo, - stage: u8, - amount: Uint128, - proof: Vec, -) -> Result { - // verify not claimed - let claimed = CLAIM.may_load(deps.storage, (&info.sender, stage))?; - if claimed.is_some() { - return Err(ContractError::Claimed {}); - } - - let config = CONFIG.load(deps.storage)?; - let merkle_root = MERKLE_ROOT.load(deps.storage, stage)?; - - let user_input = format!("{}{}", info.sender, amount); - let hash = sha2::Sha256::digest(user_input.as_bytes()) - .as_slice() - .try_into() - .map_err(|_| ContractError::WrongLength {})?; - - let hash = proof.into_iter().try_fold(hash, |hash, p| { - let mut proof_buf = [0; 32]; - hex::decode_to_slice(p, &mut proof_buf)?; - let mut hashes = [hash, proof_buf]; - hashes.sort_unstable(); - sha2::Sha256::digest(&hashes.concat()) - .as_slice() - .try_into() - .map_err(|_| ContractError::WrongLength {}) - })?; - - let mut root_buf: [u8; 32] = [0; 32]; - hex::decode_to_slice(merkle_root, &mut root_buf)?; - if root_buf != hash { - return Err(ContractError::VerificationFailed {}); - } - - // Update claim index to the current stage - CLAIM.save(deps.storage, (&info.sender, stage), &true)?; - - let res = Response::new() - .add_message(WasmMsg::Execute { - contract_addr: config.cw20_token_address.to_string(), - funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: info.sender.to_string(), - amount, - })?, - }) - .add_attributes(vec![ - attr("action", "claim"), - attr("stage", stage.to_string()), - attr("address", info.sender), - attr("amount", amount), - ]); - Ok(res) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Config {} => to_binary(&query_config(deps)?), - QueryMsg::MerkleRoot { stage } => to_binary(&query_merkle_root(deps, stage)?), - QueryMsg::LatestStage {} => to_binary(&query_latest_stage(deps)?), - QueryMsg::IsClaimed { stage, address } => { - to_binary(&query_is_claimed(deps, stage, address)?) - } - } -} - -pub fn query_config(deps: Deps) -> StdResult { - let cfg = CONFIG.load(deps.storage)?; - Ok(ConfigResponse { - owner: cfg.owner.map(|o| o.to_string()), - cw20_token_address: cfg.cw20_token_address.to_string(), - }) -} - -pub fn query_merkle_root(deps: Deps, stage: u8) -> StdResult { - let merkle_root = MERKLE_ROOT.load(deps.storage, stage)?; - let resp = MerkleRootResponse { stage, merkle_root }; - - Ok(resp) -} - -pub fn query_latest_stage(deps: Deps) -> StdResult { - let latest_stage = LATEST_STAGE.load(deps.storage)?; - let resp = LatestStageResponse { latest_stage }; - - Ok(resp) -} - -pub fn query_is_claimed(deps: Deps, stage: u8, address: String) -> StdResult { - let key: (&Addr, u8) = (&deps.api.addr_validate(&address)?, stage); - let is_claimed = CLAIM.may_load(deps.storage, key)?.unwrap_or(false); - let resp = IsClaimedResponse { is_claimed }; - - Ok(resp) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let version = get_contract_version(deps.storage)?; - if version.contract != CONTRACT_NAME { - return Err(ContractError::CannotMigrate { - previous_contract: version.contract, - }); - } - Ok(Response::default()) -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_binary, from_slice, CosmosMsg, SubMsg}; - use serde::Deserialize; - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - - let msg = InstantiateMsg { - owner: Some("owner0000".to_string()), - cw20_token_address: "anchor0000".to_string(), - }; - - let env = mock_env(); - let info = mock_info("addr0000", &[]); - - // we can just call .unwrap() to assert this was a success - let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - - // it worked, let's query the state - let res = query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap(); - let config: ConfigResponse = from_binary(&res).unwrap(); - assert_eq!("owner0000", config.owner.unwrap().as_str()); - assert_eq!("anchor0000", config.cw20_token_address.as_str()); - - let res = query(deps.as_ref(), env, QueryMsg::LatestStage {}).unwrap(); - let latest_stage: LatestStageResponse = from_binary(&res).unwrap(); - assert_eq!(0u8, latest_stage.latest_stage); - } - - #[test] - fn update_config() { - let mut deps = mock_dependencies(); - - let msg = InstantiateMsg { - owner: None, - cw20_token_address: "anchor0000".to_string(), - }; - - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - - // update owner - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::UpdateConfig { - new_owner: Some("owner0001".to_string()), - }; - - let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // it worked, let's query the state - let res = query(deps.as_ref(), env, QueryMsg::Config {}).unwrap(); - let config: ConfigResponse = from_binary(&res).unwrap(); - assert_eq!("owner0001", config.owner.unwrap().as_str()); - - // Unauthorized err - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::UpdateConfig { new_owner: None }; - - let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}); - } - - #[test] - fn register_merkle_root() { - let mut deps = mock_dependencies(); - - let msg = InstantiateMsg { - owner: Some("owner0000".to_string()), - cw20_token_address: "anchor0000".to_string(), - }; - - let env = mock_env(); - let info = mock_info("addr0000", &[]); - let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - - // register new merkle root - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: "634de21cde1044f41d90373733b0f0fb1c1c71f9652b905cdf159e73c4cf0d37" - .to_string(), - }; - - let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - assert_eq!( - res.attributes, - vec![ - attr("action", "register_merkle_root"), - attr("stage", "1"), - attr( - "merkle_root", - "634de21cde1044f41d90373733b0f0fb1c1c71f9652b905cdf159e73c4cf0d37" - ) - ] - ); - - let res = query(deps.as_ref(), env.clone(), QueryMsg::LatestStage {}).unwrap(); - let latest_stage: LatestStageResponse = from_binary(&res).unwrap(); - assert_eq!(1u8, latest_stage.latest_stage); - - let res = query( - deps.as_ref(), - env, - QueryMsg::MerkleRoot { - stage: latest_stage.latest_stage, - }, - ) - .unwrap(); - let merkle_root: MerkleRootResponse = from_binary(&res).unwrap(); - assert_eq!( - "634de21cde1044f41d90373733b0f0fb1c1c71f9652b905cdf159e73c4cf0d37".to_string(), - merkle_root.merkle_root - ); - } - - const TEST_DATA_1: &[u8] = include_bytes!("../testdata/airdrop_stage_1_test_data.json"); - const TEST_DATA_2: &[u8] = include_bytes!("../testdata/airdrop_stage_2_test_data.json"); - - #[derive(Deserialize, Debug)] - struct Encoded { - account: String, - amount: Uint128, - root: String, - proofs: Vec, - } - - #[test] - fn claim() { - // Run test 1 - let mut deps = mock_dependencies(); - let test_data: Encoded = from_slice(TEST_DATA_1).unwrap(); - - let msg = InstantiateMsg { - owner: Some("owner0000".to_string()), - cw20_token_address: "token0000".to_string(), - }; - - let env = mock_env(); - let info = mock_info("addr0000", &[]); - let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: test_data.root, - }; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - - let msg = ExecuteMsg::Claim { - amount: test_data.amount, - stage: 1u8, - proof: test_data.proofs, - }; - - let env = mock_env(); - let info = mock_info(test_data.account.as_str(), &[]); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); - let expected = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), - funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: test_data.account.clone(), - amount: test_data.amount, - }) - .unwrap(), - })); - assert_eq!(res.messages, vec![expected]); - - assert_eq!( - res.attributes, - vec![ - attr("action", "claim"), - attr("stage", "1"), - attr("address", test_data.account.clone()), - attr("amount", test_data.amount) - ] - ); - - assert!( - from_binary::( - &query( - deps.as_ref(), - env.clone(), - QueryMsg::IsClaimed { - stage: 1, - address: test_data.account - } - ) - .unwrap() - ) - .unwrap() - .is_claimed - ); - - // Second test - - let test_data: Encoded = from_slice(TEST_DATA_2).unwrap(); - // check claimed - let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::Claimed {}); - - // register new drop - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: test_data.root, - }; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - - // Claim next airdrop - let msg = ExecuteMsg::Claim { - amount: test_data.amount, - stage: 2u8, - proof: test_data.proofs, - }; - - let env = mock_env(); - let info = mock_info(test_data.account.as_str(), &[]); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - let expected: SubMsg<_> = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), - funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: test_data.account.clone(), - amount: test_data.amount, - }) - .unwrap(), - })); - assert_eq!(res.messages, vec![expected]); - - assert_eq!( - res.attributes, - vec![ - attr("action", "claim"), - attr("stage", "2"), - attr("address", test_data.account), - attr("amount", test_data.amount) - ] - ); - } - - #[test] - fn owner_freeze() { - let mut deps = mock_dependencies(); - - let msg = InstantiateMsg { - owner: Some("owner0000".to_string()), - cw20_token_address: "token0000".to_string(), - }; - - let env = mock_env(); - let info = mock_info("addr0000", &[]); - let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - - // can register merkle root - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: "5d4f48f147cb6cb742b376dce5626b2a036f69faec10cd73631c791780e150fc" - .to_string(), - }; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - - // can update owner - let env = mock_env(); - let info = mock_info("owner0000", &[]); - let msg = ExecuteMsg::UpdateConfig { - new_owner: Some("owner0001".to_string()), - }; - - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // freeze contract - let env = mock_env(); - let info = mock_info("owner0001", &[]); - let msg = ExecuteMsg::UpdateConfig { new_owner: None }; - - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // cannot register new drop - let env = mock_env(); - let info = mock_info("owner0001", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: "ebaa83c7eaf7467c378d2f37b5e46752d904d2d17acd380b24b02e3b398b3e5a" - .to_string(), - }; - let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}); - - // cannot update config - let env = mock_env(); - let info = mock_info("owner0001", &[]); - let msg = ExecuteMsg::RegisterMerkleRoot { - merkle_root: "ebaa83c7eaf7467c378d2f37b5e46752d904d2d17acd380b24b02e3b398b3e5a" - .to_string(), - }; - let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}); - } -} diff --git a/contracts/cw20-merkle-airdrop/src/error.rs b/contracts/cw20-merkle-airdrop/src/error.rs deleted file mode 100644 index 737bc68ad..000000000 --- a/contracts/cw20-merkle-airdrop/src/error.rs +++ /dev/null @@ -1,30 +0,0 @@ -use cosmwasm_std::StdError; -use hex::FromHexError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Hex(#[from] FromHexError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Invalid input")] - InvalidInput {}, - - #[error("Already claimed")] - Claimed {}, - - #[error("Wrong length")] - WrongLength {}, - - #[error("Verification failed")] - VerificationFailed {}, - - #[error("Cannot migrate from different contract type: {previous_contract}")] - CannotMigrate { previous_contract: String }, -} diff --git a/contracts/cw20-merkle-airdrop/src/lib.rs b/contracts/cw20-merkle-airdrop/src/lib.rs deleted file mode 100644 index dfedc9dc6..000000000 --- a/contracts/cw20-merkle-airdrop/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod contract; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/contracts/cw20-merkle-airdrop/src/msg.rs b/contracts/cw20-merkle-airdrop/src/msg.rs deleted file mode 100644 index 0dea179eb..000000000 --- a/contracts/cw20-merkle-airdrop/src/msg.rs +++ /dev/null @@ -1,68 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Uint128; - -#[derive(Serialize, Deserialize, JsonSchema)] -pub struct InstantiateMsg { - /// Owner if none set to info.sender. - pub owner: Option, - pub cw20_token_address: String, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - UpdateConfig { - /// NewOwner if non sent, contract gets locked. Recipients can receive airdrops - /// but owner cannot register new stages. - new_owner: Option, - }, - RegisterMerkleRoot { - /// MerkleRoot is hex-encoded merkle root. - merkle_root: String, - }, - /// Claim does not check if contract has enough funds, owner must ensure it. - Claim { - stage: u8, - amount: Uint128, - /// Proof is hex-encoded merkle proof. - proof: Vec, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - Config {}, - MerkleRoot { stage: u8 }, - LatestStage {}, - IsClaimed { stage: u8, address: String }, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct ConfigResponse { - pub owner: Option, - pub cw20_token_address: String, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MerkleRootResponse { - pub stage: u8, - /// MerkleRoot is hex-encoded merkle root. - pub merkle_root: String, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct LatestStageResponse { - pub latest_stage: u8, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct IsClaimedResponse { - pub is_claimed: bool, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MigrateMsg {} diff --git a/contracts/cw20-merkle-airdrop/src/state.rs b/contracts/cw20-merkle-airdrop/src/state.rs deleted file mode 100644 index c06471f87..000000000 --- a/contracts/cw20-merkle-airdrop/src/state.rs +++ /dev/null @@ -1,24 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Addr; -use cw_storage_plus::{Item, Map}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct Config { - /// Owner If None set, contract is frozen. - pub owner: Option, - pub cw20_token_address: Addr, -} - -pub const CONFIG_KEY: &str = "config"; -pub const CONFIG: Item = Item::new(CONFIG_KEY); - -pub const LATEST_STAGE_KEY: &str = "stage"; -pub const LATEST_STAGE: Item = Item::new(LATEST_STAGE_KEY); - -pub const MERKLE_ROOT_PREFIX: &str = "merkle_root"; -pub const MERKLE_ROOT: Map = Map::new(MERKLE_ROOT_PREFIX); - -pub const CLAIM_PREFIX: &str = "claim"; -pub const CLAIM: Map<(&Addr, u8), bool> = Map::new(CLAIM_PREFIX); diff --git a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_list.json b/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_list.json deleted file mode 100644 index 08368d7ec..000000000 --- a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_list.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { "address": "wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq", "amount": "100"}, - { "address": "wasm1uy9ucvgerneekxpnfwyfnpxvlsx5dzdpf0mzjd", "amount": "1010"}, - { "address": "wasm1a4x6au55s0fusctyj2ulrxvfpmjcxa92k7ze2v", "amount": "10220"}, - { "address": "wasm1ylna88nach9sn5n7qe7u5l6lh7dmt6lp2y63xx", "amount": "10333"}, - { "address": "wasm1qzy8rg0f406uvvl54dlww6ptlh30303xq2u3xu", "amount": "10220"}, - { "address": "wasm1xn46zz5m3fhymcrcwe82m0ac8ytt588dkpaeas", "amount": "10220"} -] - diff --git a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_test_data.json b/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_test_data.json deleted file mode 100644 index 2c8fa8c81..000000000 --- a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_1_test_data.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "account": "wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq", - "amount": "100", - "root": "b45c1ea28b26adb13e412933c9e055b01fdf7585304b00cd8f1cb220aa6c5e88", - "proofs": [ - "a714186eaedddde26b08b9afda38cf62fdf88d68e3aa0d5a4b55033487fe14a1", - "fb57090a813128eeb953a4210dd64ee73d2632b8158231effe2f0a18b2d3b5dd", - "c30992d264c74c58b636a31098c6c27a5fc08b3f61b7eafe2a33dcb445822343" - ] -} diff --git a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_list.json b/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_list.json deleted file mode 100644 index 74437e38b..000000000 --- a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_list.json +++ /dev/null @@ -1,13 +0,0 @@ -[ - { "address": "wasm1k9hwzxs889jpvd7env8z49gad3a3633vg350tq", "amount": "666666666"}, - { "address": "wasm1uy9ucvgerneekxpnfwyfnpxvlsx5dzdpf0mzjd", "amount": "1010"}, - { "address": "wasm1a4x6au55s0fusctyj2ulrxvfpmjcxa92k7ze2v", "amount": "999"}, - { "address": "wasm1ylna88nach9sn5n7qe7u5l6lh7dmt6lp2y63xx", "amount": "1000000000"}, - { "address": "wasm1qzy8rg0f406uvvl54dlww6ptlh30303xq2u3xu", "amount": "10220"}, - { "address": "wasm1c99d6aw39e027fmy5f2gj38g8p8c3cf0vn3qqn", "amount": "1322"}, - { "address": "wasm1uwcjkghqlz030r989clzqs8zlaujwyphx0yumy", "amount": "14"}, - { "address": "wasm1yggt0x0r3x5ujk96kfeps6v4yakgun8mdth90j", "amount": "9000000"}, - { "address": "wasm1f6s77fjplerjrh4yjj08msqdq36mam4xv9tjvs", "amount": "12333"}, - { "address": "wasm1xn46zz5m3fhymcrcwe82m0ac8ytt588dkpaeas", "amount": "1322"} -] - diff --git a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_test_data.json b/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_test_data.json deleted file mode 100644 index f90bfccae..000000000 --- a/contracts/cw20-merkle-airdrop/testdata/airdrop_stage_2_test_data.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "account": "wasm1uwcjkghqlz030r989clzqs8zlaujwyphx0yumy", - "amount": "14", - "root": "a5587bd4d158618b83badf57b1a4206f86e33407e18797ef690c931d73b36232", - "proofs": [ - "a714186eaedddde26b08b9afda38cf62fdf88d68e3aa0d5a4b55033487fe14a1", - "1eb08e61c40d5ba334f3c32f3f136e714f0841e5d53af6b78ec94e3b29a01e74", - "fe570ffb0015447c01bffdcd266fe4ee21a23eb6b499461b9ced5a03c6a9b2f0", - "fa0224da936bcebd0f018a46ba15a5a9fc2d637f72f7c14b31aeffd8964983b5" - ] -} diff --git a/contracts/cw20-staking/.cargo/config b/contracts/cw20-staking/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/contracts/cw20-staking/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/contracts/cw20-staking/Cargo.toml b/contracts/cw20-staking/Cargo.toml deleted file mode 100644 index 0275d354b..000000000 --- a/contracts/cw20-staking/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "cw20-staking" -version = "0.11.1" -authors = ["Ethan Frey "] -edition = "2018" -description = "Implement simple staking derivatives as a cw20 token" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } -cw20-base = { path = "../../contracts/cw20-base", version = "0.11.1", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } diff --git a/contracts/cw20-staking/NOTICE b/contracts/cw20-staking/NOTICE deleted file mode 100644 index f785e88f3..000000000 --- a/contracts/cw20-staking/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-Staking: Staking Derivatives as a CW20 token -Copyright 2020 Ethan Frey - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-staking/README.md b/contracts/cw20-staking/README.md deleted file mode 100644 index 9a23707dc..000000000 --- a/contracts/cw20-staking/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Staking Derivatives - -This is a sample contract that releases a minimal form of staking derivatives. -This is to be used for integration tests and as a foundation for other to build -more complex logic upon. - -## Functionality - -On one side, this acts as a CW20 token, holding a list of -balances for multiple addresses, and exposing queries and transfers (no -allowances and "transfer from" to focus the logic on the staking stuff). -However, it has no initial balance. Instead, it mints and burns them based on -delegations. - -For such a "bonding curve" we expose two additional message types. A "bond" -message sends native staking tokens to the contract to be bonded to a validator -and credits the user with the appropriate amount of derivative tokens. Likewise -you can burn some of your derivative tokens, and the contract will unbond the -proportional amount of stake to the user's account (after typical 21-day -unbonding period). - -To show an example of charging for such a service, we allow the contract owner -to take a small exit tax, thus maybe 98% of the tokens will be unbonded and sent -to the original account, and 2% of the tokens are not unbonded, but rather -transferred to the owners account. (The ownership can also be transferred). diff --git a/contracts/cw20-staking/examples/schema.rs b/contracts/cw20-staking/examples/schema.rs deleted file mode 100644 index f60ed253a..000000000 --- a/contracts/cw20-staking/examples/schema.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20::{AllowanceResponse, BalanceResponse, TokenInfoResponse}; -use cw20_staking::msg::{ClaimsResponse, ExecuteMsg, InstantiateMsg, InvestmentResponse, QueryMsg}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(AllowanceResponse), &out_dir); - export_schema(&schema_for!(BalanceResponse), &out_dir); - export_schema(&schema_for!(ClaimsResponse), &out_dir); - export_schema(&schema_for!(InvestmentResponse), &out_dir); - export_schema(&schema_for!(TokenInfoResponse), &out_dir); -} diff --git a/contracts/cw20-staking/src/contract.rs b/contracts/cw20-staking/src/contract.rs deleted file mode 100644 index a64dc0174..000000000 --- a/contracts/cw20-staking/src/contract.rs +++ /dev/null @@ -1,965 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - coin, to_binary, Addr, BankMsg, Binary, Decimal, Deps, DepsMut, DistributionMsg, Env, - MessageInfo, QuerierWrapper, Response, StakingMsg, StdError, StdResult, Uint128, WasmMsg, -}; - -use cw2::set_contract_version; -use cw20_base::allowances::{ - execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from, - execute_transfer_from, query_allowance, -}; -use cw20_base::contract::{ - execute_burn, execute_mint, execute_send, execute_transfer, query_balance, query_token_info, -}; -use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO}; - -use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, InvestmentResponse, QueryMsg}; -use crate::state::{InvestmentInfo, Supply, CLAIMS, INVESTMENT, TOTAL_SUPPLY}; - -const FALLBACK_RATIO: Decimal = Decimal::one(); - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw20-staking"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // ensure the validator is registered - let vals = deps.querier.query_all_validators()?; - if !vals.iter().any(|v| v.address == msg.validator) { - return Err(ContractError::NotInValidatorSet { - validator: msg.validator, - }); - } - - // store token info using cw20-base format - let data = TokenInfo { - name: msg.name, - symbol: msg.symbol, - decimals: msg.decimals, - total_supply: Uint128::zero(), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address, - cap: None, - }), - }; - TOKEN_INFO.save(deps.storage, &data)?; - - let denom = deps.querier.query_bonded_denom()?; - let invest = InvestmentInfo { - owner: info.sender, - exit_tax: msg.exit_tax, - unbonding_period: msg.unbonding_period, - bond_denom: denom, - validator: msg.validator, - min_withdrawal: msg.min_withdrawal, - }; - INVESTMENT.save(deps.storage, &invest)?; - - // set supply to 0 - let supply = Supply::default(); - TOTAL_SUPPLY.save(deps.storage, &supply)?; - - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Bond {} => bond(deps, env, info), - ExecuteMsg::Unbond { amount } => unbond(deps, env, info, amount), - ExecuteMsg::Claim {} => claim(deps, env, info), - ExecuteMsg::Reinvest {} => reinvest(deps, env, info), - ExecuteMsg::_BondAllTokens {} => _bond_all_tokens(deps, env, info), - - // these all come from cw20-base to implement the cw20 standard - ExecuteMsg::Transfer { recipient, amount } => { - Ok(execute_transfer(deps, env, info, recipient, amount)?) - } - ExecuteMsg::Burn { amount } => Ok(execute_burn(deps, env, info, amount)?), - ExecuteMsg::Send { - contract, - amount, - msg, - } => Ok(execute_send(deps, env, info, contract, amount, msg)?), - ExecuteMsg::IncreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_increase_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::DecreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_decrease_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::TransferFrom { - owner, - recipient, - amount, - } => Ok(execute_transfer_from( - deps, env, info, owner, recipient, amount, - )?), - ExecuteMsg::BurnFrom { owner, amount } => { - Ok(execute_burn_from(deps, env, info, owner, amount)?) - } - ExecuteMsg::SendFrom { - owner, - contract, - amount, - msg, - } => Ok(execute_send_from( - deps, env, info, owner, contract, amount, msg, - )?), - } -} - -// get_bonded returns the total amount of delegations from contract -// it ensures they are all the same denom -fn get_bonded(querier: &QuerierWrapper, contract: &Addr) -> Result { - let bonds = querier.query_all_delegations(contract)?; - if bonds.is_empty() { - return Ok(Uint128::zero()); - } - let denom = bonds[0].amount.denom.as_str(); - bonds.iter().fold(Ok(Uint128::zero()), |racc, d| { - let acc = racc?; - if d.amount.denom.as_str() != denom { - Err(ContractError::DifferentBondDenom { - denom1: denom.into(), - denom2: d.amount.denom.to_string(), - }) - } else { - Ok(acc + d.amount.amount) - } - }) -} - -fn assert_bonds(supply: &Supply, bonded: Uint128) -> Result<(), ContractError> { - if supply.bonded != bonded { - Err(ContractError::BondedMismatch { - stored: supply.bonded, - queried: bonded, - }) - } else { - Ok(()) - } -} - -pub fn bond(deps: DepsMut, env: Env, info: MessageInfo) -> Result { - // ensure we have the proper denom - let invest = INVESTMENT.load(deps.storage)?; - // payment finds the proper coin (or throws an error) - let payment = info - .funds - .iter() - .find(|x| x.denom == invest.bond_denom) - .ok_or_else(|| ContractError::EmptyBalance { - denom: invest.bond_denom.clone(), - })?; - - // bonded is the total number of tokens we have delegated from this address - let bonded = get_bonded(&deps.querier, &env.contract.address)?; - - // calculate to_mint and update total supply - let mut supply = TOTAL_SUPPLY.load(deps.storage)?; - // TODO: this is just a safety assertion - do we keep it, or remove caching? - // in the end supply is just there to cache the (expected) results of get_bonded() so we don't - // have expensive queries everywhere - assert_bonds(&supply, bonded)?; - let to_mint = if supply.issued.is_zero() || bonded.is_zero() { - FALLBACK_RATIO * payment.amount - } else { - payment.amount.multiply_ratio(supply.issued, bonded) - }; - supply.bonded = bonded + payment.amount; - supply.issued += to_mint; - TOTAL_SUPPLY.save(deps.storage, &supply)?; - - // call into cw20-base to mint the token, call as self as no one else is allowed - let sub_info = MessageInfo { - sender: env.contract.address.clone(), - funds: vec![], - }; - execute_mint(deps, env, sub_info, info.sender.to_string(), to_mint)?; - - // bond them to the validator - let res = Response::new() - .add_message(StakingMsg::Delegate { - validator: invest.validator, - amount: payment.clone(), - }) - .add_attribute("action", "bond") - .add_attribute("from", info.sender) - .add_attribute("bonded", payment.amount) - .add_attribute("minted", to_mint); - Ok(res) -} - -pub fn unbond( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - amount: Uint128, -) -> Result { - let invest = INVESTMENT.load(deps.storage)?; - // ensure it is big enough to care - if amount < invest.min_withdrawal { - return Err(ContractError::UnbondTooSmall { - min_bonded: invest.min_withdrawal, - denom: invest.bond_denom, - }); - } - // calculate tax and remainer to unbond - let tax = amount * invest.exit_tax; - - // burn from the original caller - execute_burn(deps.branch(), env.clone(), info.clone(), amount)?; - if tax > Uint128::zero() { - let sub_info = MessageInfo { - sender: env.contract.address.clone(), - funds: vec![], - }; - // call into cw20-base to mint tokens to owner, call as self as no one else is allowed - execute_mint( - deps.branch(), - env.clone(), - sub_info, - invest.owner.to_string(), - tax, - )?; - } - - // re-calculate bonded to ensure we have real values - // bonded is the total number of tokens we have delegated from this address - let bonded = get_bonded(&deps.querier, &env.contract.address)?; - - // calculate how many native tokens this is worth and update supply - let remainder = amount.checked_sub(tax).map_err(StdError::overflow)?; - let mut supply = TOTAL_SUPPLY.load(deps.storage)?; - // TODO: this is just a safety assertion - do we keep it, or remove caching? - // in the end supply is just there to cache the (expected) results of get_bonded() so we don't - // have expensive queries everywhere - assert_bonds(&supply, bonded)?; - let unbond = remainder.multiply_ratio(bonded, supply.issued); - supply.bonded = bonded.checked_sub(unbond).map_err(StdError::overflow)?; - supply.issued = supply - .issued - .checked_sub(remainder) - .map_err(StdError::overflow)?; - supply.claims += unbond; - TOTAL_SUPPLY.save(deps.storage, &supply)?; - - CLAIMS.create_claim( - deps.storage, - &info.sender, - unbond, - invest.unbonding_period.after(&env.block), - )?; - - // unbond them - let res = Response::new() - .add_message(StakingMsg::Undelegate { - validator: invest.validator, - amount: coin(unbond.u128(), &invest.bond_denom), - }) - .add_attribute("action", "unbond") - .add_attribute("to", info.sender) - .add_attribute("unbonded", unbond) - .add_attribute("burnt", amount); - Ok(res) -} - -pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> Result { - // find how many tokens the contract has - let invest = INVESTMENT.load(deps.storage)?; - let mut balance = deps - .querier - .query_balance(&env.contract.address, &invest.bond_denom)?; - if balance.amount < invest.min_withdrawal { - return Err(ContractError::BalanceTooSmall {}); - } - - // check how much to send - min(balance, claims[sender]), and reduce the claim - // Ensure we have enough balance to cover this and only send some claims if that is all we can cover - let to_send = - CLAIMS.claim_tokens(deps.storage, &info.sender, &env.block, Some(balance.amount))?; - if to_send == Uint128::zero() { - return Err(ContractError::NothingToClaim {}); - } - - // update total supply (lower claim) - TOTAL_SUPPLY.update(deps.storage, |mut supply| -> StdResult<_> { - supply.claims = supply.claims.checked_sub(to_send)?; - Ok(supply) - })?; - - // transfer tokens to the sender - balance.amount = to_send; - let res = Response::new() - .add_message(BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![balance], - }) - .add_attribute("action", "claim") - .add_attribute("from", info.sender) - .add_attribute("amount", to_send); - Ok(res) -} - -/// reinvest will withdraw all pending rewards, -/// then issue a callback to itself via _bond_all_tokens -/// to reinvest the new earnings (and anything else that accumulated) -pub fn reinvest(deps: DepsMut, env: Env, _info: MessageInfo) -> Result { - let contract_addr = env.contract.address; - let invest = INVESTMENT.load(deps.storage)?; - let msg = to_binary(&ExecuteMsg::_BondAllTokens {})?; - - // and bond them to the validator - let res = Response::new() - .add_message(DistributionMsg::WithdrawDelegatorReward { - validator: invest.validator, - }) - .add_message(WasmMsg::Execute { - contract_addr: contract_addr.to_string(), - msg, - funds: vec![], - }); - Ok(res) -} - -pub fn _bond_all_tokens( - deps: DepsMut, - env: Env, - info: MessageInfo, -) -> Result { - // this is just meant as a call-back to ourself - if info.sender != env.contract.address { - return Err(ContractError::Unauthorized {}); - } - - // find how many tokens we have to bond - let invest = INVESTMENT.load(deps.storage)?; - let mut balance = deps - .querier - .query_balance(&env.contract.address, &invest.bond_denom)?; - - // we deduct pending claims from our account balance before reinvesting. - // if there is not enough funds, we just return a no-op - match TOTAL_SUPPLY.update(deps.storage, |mut supply| -> StdResult<_> { - balance.amount = balance.amount.checked_sub(supply.claims)?; - // this just triggers the "no op" case if we don't have min_withdrawal left to reinvest - balance.amount.checked_sub(invest.min_withdrawal)?; - supply.bonded += balance.amount; - Ok(supply) - }) { - Ok(_) => {} - // if it is below the minimum, we do a no-op (do not revert other state from withdrawal) - Err(StdError::Overflow { .. }) => return Ok(Response::default()), - Err(e) => return Err(ContractError::Std(e)), - } - - // and bond them to the validator - let res = Response::new() - .add_message(StakingMsg::Delegate { - validator: invest.validator, - amount: balance.clone(), - }) - .add_attribute("action", "reinvest") - .add_attribute("bonded", balance.amount); - Ok(res) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - // custom queries - QueryMsg::Claims { address } => { - to_binary(&CLAIMS.query_claims(deps, &deps.api.addr_validate(&address)?)?) - } - QueryMsg::Investment {} => to_binary(&query_investment(deps)?), - // inherited from cw20-base - QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?), - QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?), - QueryMsg::Allowance { owner, spender } => { - to_binary(&query_allowance(deps, owner, spender)?) - } - } -} - -pub fn query_investment(deps: Deps) -> StdResult { - let invest = INVESTMENT.load(deps.storage)?; - let supply = TOTAL_SUPPLY.load(deps.storage)?; - - let res = InvestmentResponse { - owner: invest.owner.to_string(), - exit_tax: invest.exit_tax, - validator: invest.validator, - min_withdrawal: invest.min_withdrawal, - token_supply: supply.issued, - staked_tokens: coin(supply.bonded.u128(), &invest.bond_denom), - nominal_value: if supply.issued.is_zero() { - FALLBACK_RATIO - } else { - Decimal::from_ratio(supply.bonded, supply.issued) - }, - }; - Ok(res) -} - -#[cfg(test)] -mod tests { - use super::*; - use std::str::FromStr; - - use cosmwasm_std::testing::{ - mock_dependencies, mock_env, mock_info, MockQuerier, MOCK_CONTRACT_ADDR, - }; - use cosmwasm_std::{ - coins, Coin, CosmosMsg, Decimal, FullDelegation, OverflowError, OverflowOperation, - Validator, - }; - use cw_controllers::Claim; - use cw_utils::{Duration, DAY, HOUR, WEEK}; - - fn sample_validator(addr: &str) -> Validator { - Validator { - address: addr.into(), - commission: Decimal::percent(3), - max_commission: Decimal::percent(10), - max_change_rate: Decimal::percent(1), - } - } - - fn sample_delegation(addr: &str, amount: Coin) -> FullDelegation { - let can_redelegate = amount.clone(); - let accumulated_rewards = coins(0, &amount.denom); - FullDelegation { - validator: addr.into(), - delegator: Addr::unchecked(MOCK_CONTRACT_ADDR), - amount, - can_redelegate, - accumulated_rewards, - } - } - - fn set_validator(querier: &mut MockQuerier) { - querier.update_staking("ustake", &[sample_validator(DEFAULT_VALIDATOR)], &[]); - } - - fn set_delegation(querier: &mut MockQuerier, amount: u128, denom: &str) { - querier.update_staking( - "ustake", - &[sample_validator(DEFAULT_VALIDATOR)], - &[sample_delegation(DEFAULT_VALIDATOR, coin(amount, denom))], - ); - } - - // just a test helper, forgive the panic - fn later(env: &Env, delta: Duration) -> Env { - let time_delta = match delta { - Duration::Time(t) => t, - _ => panic!("Must provide duration in time"), - }; - let mut res = env.clone(); - res.block.time = res.block.time.plus_seconds(time_delta); - res - } - - const DEFAULT_VALIDATOR: &str = "default-validator"; - - fn default_instantiate(tax_percent: u64, min_withdrawal: u128) -> InstantiateMsg { - InstantiateMsg { - name: "Cool Derivative".to_string(), - symbol: "DRV".to_string(), - decimals: 9, - validator: String::from(DEFAULT_VALIDATOR), - unbonding_period: DAY * 3, - exit_tax: Decimal::percent(tax_percent), - min_withdrawal: Uint128::new(min_withdrawal), - } - } - - fn get_balance>(deps: Deps, addr: U) -> Uint128 { - query_balance(deps, addr.into()).unwrap().balance - } - - fn get_claims(deps: Deps, addr: &str) -> Vec { - CLAIMS - .query_claims(deps, &Addr::unchecked(addr)) - .unwrap() - .claims - } - - #[test] - fn instantiation_with_missing_validator() { - let mut deps = mock_dependencies(); - deps.querier - .update_staking("ustake", &[sample_validator("john")], &[]); - - let creator = String::from("creator"); - let msg = InstantiateMsg { - name: "Cool Derivative".to_string(), - symbol: "DRV".to_string(), - decimals: 9, - validator: String::from("my-validator"), - unbonding_period: WEEK, - exit_tax: Decimal::percent(2), - min_withdrawal: Uint128::new(50), - }; - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let err = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap_err(); - assert_eq!( - err, - ContractError::NotInValidatorSet { - validator: "my-validator".into() - } - ); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - deps.querier.update_staking( - "ustake", - &[ - sample_validator("john"), - sample_validator("mary"), - sample_validator("my-validator"), - ], - &[], - ); - - let creator = String::from("creator"); - let msg = InstantiateMsg { - name: "Cool Derivative".to_string(), - symbol: "DRV".to_string(), - decimals: 0, - validator: String::from("my-validator"), - unbonding_period: HOUR * 12, - exit_tax: Decimal::percent(2), - min_withdrawal: Uint128::new(50), - }; - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, msg.clone()).unwrap(); - assert_eq!(0, res.messages.len()); - - // token info is proper - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(&token.name, &msg.name); - assert_eq!(&token.symbol, &msg.symbol); - assert_eq!(token.decimals, msg.decimals); - assert_eq!(token.total_supply, Uint128::zero()); - - // no balance - assert_eq!(get_balance(deps.as_ref(), &creator), Uint128::zero()); - // no claims - assert_eq!(get_claims(deps.as_ref(), &creator), vec![]); - - // investment info correct - let invest = query_investment(deps.as_ref()).unwrap(); - assert_eq!(&invest.owner, &creator); - assert_eq!(&invest.validator, &msg.validator); - assert_eq!(invest.exit_tax, msg.exit_tax); - assert_eq!(invest.min_withdrawal, msg.min_withdrawal); - - assert_eq!(invest.token_supply, Uint128::zero()); - assert_eq!(invest.staked_tokens, coin(0, "ustake")); - assert_eq!(invest.nominal_value, Decimal::one()); - } - - #[test] - fn bonding_issues_tokens() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(2, 50); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // let's bond some tokens now - let bob = String::from("bob"); - let bond_msg = ExecuteMsg::Bond {}; - let info = mock_info(&bob, &[coin(10, "random"), coin(1000, "ustake")]); - - // try to bond and make sure we trigger delegation - let res = execute(deps.as_mut(), mock_env(), info, bond_msg).unwrap(); - assert_eq!(1, res.messages.len()); - let delegate = &res.messages[0]; - match &delegate.msg { - CosmosMsg::Staking(StakingMsg::Delegate { validator, amount }) => { - assert_eq!(validator.as_str(), DEFAULT_VALIDATOR); - assert_eq!(amount, &coin(1000, "ustake")); - } - _ => panic!("Unexpected message: {:?}", delegate), - } - - // bob got 1000 DRV for 1000 stake at a 1.0 ratio - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(1000)); - - // investment info correct (updated supply) - let invest = query_investment(deps.as_ref()).unwrap(); - assert_eq!(invest.token_supply, Uint128::new(1000)); - assert_eq!(invest.staked_tokens, coin(1000, "ustake")); - assert_eq!(invest.nominal_value, Decimal::one()); - - // token info also properly updated - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(token.total_supply, Uint128::new(1000)); - } - - #[test] - fn rebonding_changes_pricing() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(2, 50); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // let's bond some tokens now - let bob = String::from("bob"); - let bond_msg = ExecuteMsg::Bond {}; - let info = mock_info(&bob, &[coin(10, "random"), coin(1000, "ustake")]); - let res = execute(deps.as_mut(), mock_env(), info, bond_msg).unwrap(); - assert_eq!(1, res.messages.len()); - - // update the querier with new bond - set_delegation(&mut deps.querier, 1000, "ustake"); - - // fake a reinvestment (this must be sent by the contract itself) - let rebond_msg = ExecuteMsg::_BondAllTokens {}; - let info = mock_info(MOCK_CONTRACT_ADDR, &[]); - deps.querier - .update_balance(MOCK_CONTRACT_ADDR, coins(500, "ustake")); - let _ = execute(deps.as_mut(), mock_env(), info, rebond_msg).unwrap(); - - // update the querier with new bond - set_delegation(&mut deps.querier, 1500, "ustake"); - - // we should now see 1000 issues and 1500 bonded (and a price of 1.5) - let invest = query_investment(deps.as_ref()).unwrap(); - assert_eq!(invest.token_supply, Uint128::new(1000)); - assert_eq!(invest.staked_tokens, coin(1500, "ustake")); - let ratio = Decimal::from_str("1.5").unwrap(); - assert_eq!(invest.nominal_value, ratio); - - // we bond some other tokens and get a different issuance price (maintaining the ratio) - let alice = String::from("alice"); - let bond_msg = ExecuteMsg::Bond {}; - let info = mock_info(&alice, &[coin(3000, "ustake")]); - let res = execute(deps.as_mut(), mock_env(), info, bond_msg).unwrap(); - assert_eq!(1, res.messages.len()); - - // update the querier with new bond - set_delegation(&mut deps.querier, 3000, "ustake"); - - // alice should have gotten 2000 DRV for the 3000 stake, keeping the ratio at 1.5 - assert_eq!(get_balance(deps.as_ref(), &alice), Uint128::new(2000)); - - let invest = query_investment(deps.as_ref()).unwrap(); - assert_eq!(invest.token_supply, Uint128::new(3000)); - assert_eq!(invest.staked_tokens, coin(4500, "ustake")); - assert_eq!(invest.nominal_value, ratio); - } - - #[test] - fn bonding_fails_with_wrong_denom() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(2, 50); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // let's bond some tokens now - let bob = String::from("bob"); - let bond_msg = ExecuteMsg::Bond {}; - let info = mock_info(&bob, &[coin(500, "photon")]); - - // try to bond and make sure we trigger delegation - let err = execute(deps.as_mut(), mock_env(), info, bond_msg).unwrap_err(); - assert_eq!( - err, - ContractError::EmptyBalance { - denom: "ustake".to_string() - } - ); - } - - #[test] - fn unbonding_maintains_price_ratio() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(10, 50); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // let's bond some tokens now - let bob = String::from("bob"); - let bond_msg = ExecuteMsg::Bond {}; - let info = mock_info(&bob, &[coin(10, "random"), coin(1000, "ustake")]); - let res = execute(deps.as_mut(), mock_env(), info, bond_msg).unwrap(); - assert_eq!(1, res.messages.len()); - - // update the querier with new bond - set_delegation(&mut deps.querier, 1000, "ustake"); - - // fake a reinvestment (this must be sent by the contract itself) - // after this, we see 1000 issues and 1500 bonded (and a price of 1.5) - let rebond_msg = ExecuteMsg::_BondAllTokens {}; - let info = mock_info(MOCK_CONTRACT_ADDR, &[]); - deps.querier - .update_balance(MOCK_CONTRACT_ADDR, coins(500, "ustake")); - let _ = execute(deps.as_mut(), mock_env(), info, rebond_msg).unwrap(); - - // update the querier with new bond, lower balance - set_delegation(&mut deps.querier, 1500, "ustake"); - deps.querier.update_balance(MOCK_CONTRACT_ADDR, vec![]); - - // creator now tries to unbond these tokens - this must fail - let unbond_msg = ExecuteMsg::Unbond { - amount: Uint128::new(600), - }; - let info = mock_info(&creator, &[]); - let err = execute(deps.as_mut(), mock_env(), info, unbond_msg).unwrap_err(); - assert_eq!( - err, - ContractError::Std(StdError::overflow(OverflowError::new( - OverflowOperation::Sub, - 0, - 600 - ))) - ); - - // bob unbonds 600 tokens at 10% tax... - // 60 are taken and send to the owner - // 540 are unbonded in exchange for 540 * 1.5 = 810 native tokens - let unbond_msg = ExecuteMsg::Unbond { - amount: Uint128::new(600), - }; - let owner_cut = Uint128::new(60); - let bobs_claim = Uint128::new(810); - let bobs_balance = Uint128::new(400); - let env = mock_env(); - let info = mock_info(&bob, &[]); - let res = execute(deps.as_mut(), env.clone(), info, unbond_msg).unwrap(); - assert_eq!(1, res.messages.len()); - let delegate = &res.messages[0]; - match &delegate.msg { - CosmosMsg::Staking(StakingMsg::Undelegate { validator, amount }) => { - assert_eq!(validator.as_str(), DEFAULT_VALIDATOR); - assert_eq!(amount, &coin(bobs_claim.u128(), "ustake")); - } - _ => panic!("Unexpected message: {:?}", delegate), - } - - // update the querier with new bond, lower balance - set_delegation(&mut deps.querier, 690, "ustake"); - - // check balances - assert_eq!(get_balance(deps.as_ref(), &bob), bobs_balance); - assert_eq!(get_balance(deps.as_ref(), &creator), owner_cut); - // proper claims - let expected_claims = vec![Claim { - amount: bobs_claim, - release_at: (DAY * 3).after(&env.block), - }]; - assert_eq!(expected_claims, get_claims(deps.as_ref(), &bob)); - - // supplies updated, ratio the same (1.5) - let ratio = Decimal::from_str("1.5").unwrap(); - - let invest = query_investment(deps.as_ref()).unwrap(); - assert_eq!(invest.token_supply, bobs_balance + owner_cut); - assert_eq!(invest.staked_tokens, coin(690, "ustake")); // 1500 - 810 - assert_eq!(invest.nominal_value, ratio); - } - - #[test] - fn claims_paid_out_properly() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - // create contract - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(10, 50); - let info = mock_info(&creator, &[]); - instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - - // bond some tokens - let bob = String::from("bob"); - let info = mock_info(&bob, &coins(1000, "ustake")); - execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Bond {}).unwrap(); - set_delegation(&mut deps.querier, 1000, "ustake"); - - // unbond part of them - let unbond_msg = ExecuteMsg::Unbond { - amount: Uint128::new(600), - }; - let env = mock_env(); - let info = mock_info(&bob, &[]); - execute(deps.as_mut(), env.clone(), info.clone(), unbond_msg).unwrap(); - set_delegation(&mut deps.querier, 460, "ustake"); - - // ensure claims are proper - let bobs_claim = Uint128::new(540); - let original_claims = vec![Claim { - amount: bobs_claim, - release_at: (DAY * 3).after(&env.block), - }]; - assert_eq!(original_claims, get_claims(deps.as_ref(), &bob)); - - // bob cannot exercise claims without enough balance - let claim_ready = later(&env, (DAY * 3 + HOUR).unwrap()); - let too_soon = later(&env, DAY); - let fail = execute( - deps.as_mut(), - claim_ready.clone(), - info.clone(), - ExecuteMsg::Claim {}, - ); - assert!(fail.is_err(), "{:?}", fail); - - // provide the balance, but claim not yet mature - also prohibited - deps.querier - .update_balance(MOCK_CONTRACT_ADDR, coins(540, "ustake")); - let fail = execute(deps.as_mut(), too_soon, info.clone(), ExecuteMsg::Claim {}); - assert!(fail.is_err(), "{:?}", fail); - - // this should work with cash and claims ready - let res = execute(deps.as_mut(), claim_ready, info, ExecuteMsg::Claim {}).unwrap(); - assert_eq!(1, res.messages.len()); - let payout = &res.messages[0]; - match &payout.msg { - CosmosMsg::Bank(BankMsg::Send { to_address, amount }) => { - assert_eq!(amount, &coins(540, "ustake")); - assert_eq!(to_address, &bob); - } - _ => panic!("Unexpected message: {:?}", payout), - } - - // claims have been removed - assert_eq!(get_claims(deps.as_ref(), &bob), vec![]); - } - - #[test] - fn cw20_imports_work() { - let mut deps = mock_dependencies(); - set_validator(&mut deps.querier); - - // set the actors... bob stakes, sends coins to carl, and gives allowance to alice - let bob = String::from("bob"); - let alice = String::from("alice"); - let carl = String::from("carl"); - - // create the contract - let creator = String::from("creator"); - let instantiate_msg = default_instantiate(2, 50); - let info = mock_info(&creator, &[]); - instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - - // bond some tokens to create a balance - let info = mock_info(&bob, &[coin(10, "random"), coin(1000, "ustake")]); - execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Bond {}).unwrap(); - - // bob got 1000 DRV for 1000 stake at a 1.0 ratio - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(1000)); - - // send coins to carl - let bob_info = mock_info(&bob, &[]); - let transfer = ExecuteMsg::Transfer { - recipient: carl.clone(), - amount: Uint128::new(200), - }; - execute(deps.as_mut(), mock_env(), bob_info.clone(), transfer).unwrap(); - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(800)); - assert_eq!(get_balance(deps.as_ref(), &carl), Uint128::new(200)); - - // allow alice - let allow = ExecuteMsg::IncreaseAllowance { - spender: alice.clone(), - amount: Uint128::new(350), - expires: None, - }; - execute(deps.as_mut(), mock_env(), bob_info.clone(), allow).unwrap(); - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(800)); - assert_eq!(get_balance(deps.as_ref(), &alice), Uint128::zero()); - assert_eq!( - query_allowance(deps.as_ref(), bob.clone(), alice.clone()) - .unwrap() - .allowance, - Uint128::new(350) - ); - - // alice takes some for herself - let self_pay = ExecuteMsg::TransferFrom { - owner: bob.clone(), - recipient: alice.clone(), - amount: Uint128::new(250), - }; - let alice_info = mock_info(&alice, &[]); - execute(deps.as_mut(), mock_env(), alice_info, self_pay).unwrap(); - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(550)); - assert_eq!(get_balance(deps.as_ref(), &alice), Uint128::new(250)); - assert_eq!( - query_allowance(deps.as_ref(), bob.clone(), alice) - .unwrap() - .allowance, - Uint128::new(100) - ); - - // burn some, but not too much - let burn_too_much = ExecuteMsg::Burn { - amount: Uint128::new(1000), - }; - let failed = execute(deps.as_mut(), mock_env(), bob_info.clone(), burn_too_much); - assert!(failed.is_err()); - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(550)); - let burn = ExecuteMsg::Burn { - amount: Uint128::new(130), - }; - execute(deps.as_mut(), mock_env(), bob_info, burn).unwrap(); - assert_eq!(get_balance(deps.as_ref(), &bob), Uint128::new(420)); - } -} diff --git a/contracts/cw20-staking/src/error.rs b/contracts/cw20-staking/src/error.rs deleted file mode 100644 index 521945d39..000000000 --- a/contracts/cw20-staking/src/error.rs +++ /dev/null @@ -1,69 +0,0 @@ -use cosmwasm_std::{StdError, Uint128}; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Validator '{validator}' not in current validator set")] - NotInValidatorSet { validator: String }, - - #[error("Different denominations in bonds: '{denom1}' vs. '{denom2}'")] - DifferentBondDenom { denom1: String, denom2: String }, - - #[error("Stored bonded {stored}, but query bonded {queried}")] - BondedMismatch { stored: Uint128, queried: Uint128 }, - - #[error("No {denom} tokens sent")] - EmptyBalance { denom: String }, - - #[error("Must unbond at least {min_bonded} {denom}")] - UnbondTooSmall { min_bonded: Uint128, denom: String }, - - #[error("Insufficient balance in contract to process claim")] - BalanceTooSmall {}, - - #[error("No claims that can be released currently")] - NothingToClaim {}, - - #[error("Cannot set to own account")] - CannotSetOwnAccount {}, - - #[error("Invalid zero amount")] - InvalidZeroAmount {}, - - #[error("Allowance is expired")] - Expired {}, - - #[error("No allowance for this account")] - NoAllowance {}, - - #[error("Minting cannot exceed the cap")] - CannotExceedCap {}, -} - -impl From for ContractError { - fn from(err: cw20_base::ContractError) -> Self { - match err { - cw20_base::ContractError::Std(error) => ContractError::Std(error), - cw20_base::ContractError::Unauthorized {} => ContractError::Unauthorized {}, - cw20_base::ContractError::CannotSetOwnAccount {} => { - ContractError::CannotSetOwnAccount {} - } - cw20_base::ContractError::InvalidZeroAmount {} => ContractError::InvalidZeroAmount {}, - cw20_base::ContractError::Expired {} => ContractError::Expired {}, - cw20_base::ContractError::NoAllowance {} => ContractError::NoAllowance {}, - cw20_base::ContractError::CannotExceedCap {} => ContractError::CannotExceedCap {}, - // This should never happen, as this contract doesn't use logo - cw20_base::ContractError::LogoTooBig {} - | cw20_base::ContractError::InvalidPngHeader {} - | cw20_base::ContractError::InvalidXmlPreamble {} => { - ContractError::Std(StdError::generic_err(err.to_string())) - } - } - } -} diff --git a/contracts/cw20-staking/src/lib.rs b/contracts/cw20-staking/src/lib.rs deleted file mode 100644 index dfedc9dc6..000000000 --- a/contracts/cw20-staking/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod contract; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/contracts/cw20-staking/src/msg.rs b/contracts/cw20-staking/src/msg.rs deleted file mode 100644 index b9c22f11b..000000000 --- a/contracts/cw20-staking/src/msg.rs +++ /dev/null @@ -1,130 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Binary, Coin, Decimal, Uint128}; -use cw20::Expiration; -pub use cw_controllers::ClaimsResponse; -use cw_utils::Duration; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - /// name of the derivative token - pub name: String, - /// symbol / ticker of the derivative token - pub symbol: String, - /// decimal places of the derivative token (for UI) - pub decimals: u8, - - /// This is the validator that all tokens will be bonded to - pub validator: String, - /// This is the unbonding period of the native staking module - /// We need this to only allow claims to be redeemed after the money has arrived - pub unbonding_period: Duration, - - /// this is how much the owner takes as a cut when someone unbonds - pub exit_tax: Decimal, - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - /// Bond will bond all staking tokens sent with the message and release derivative tokens - Bond {}, - /// Unbond will "burn" the given amount of derivative tokens and send the unbonded - /// staking tokens to the message sender (after exit tax is deducted) - Unbond { amount: Uint128 }, - /// Claim is used to claim your native tokens that you previously "unbonded" - /// after the chain-defined waiting period (eg. 3 weeks) - Claim {}, - /// Reinvest will check for all accumulated rewards, withdraw them, and - /// re-bond them to the same validator. Anyone can call this, which updates - /// the value of the token (how much under custody). - Reinvest {}, - /// _BondAllTokens can only be called by the contract itself, after all rewards have been - /// withdrawn. This is an example of using "callbacks" in message flows. - /// This can only be invoked by the contract itself as a return from Reinvest - _BondAllTokens {}, - - /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions - Transfer { recipient: String, amount: Uint128 }, - /// Implements CW20. Burn is a base message to destroy tokens forever - Burn { amount: Uint128 }, - /// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action - /// on the receiving contract. - Send { - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens - /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance - /// expiration with this one. - IncreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Lowers the spender's access of tokens - /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current - /// allowance expiration with this one. - DecreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient - /// if `env.sender` has sufficient pre-approval. - TransferFrom { - owner: String, - recipient: String, - amount: Uint128, - }, - /// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract - /// if `env.sender` has sufficient pre-approval. - SendFrom { - owner: String, - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Destroys tokens forever - BurnFrom { owner: String, amount: Uint128 }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Claims shows the number of tokens this address can access when they are done unbonding - Claims { address: String }, - /// Investment shows metadata on the staking info of the contract - Investment {}, - - /// Implements CW20. Returns the current balance of the given address, 0 if unset. - Balance { address: String }, - /// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc. - TokenInfo {}, - /// Implements CW20 "allowance" extension. - /// Returns how much spender can use from owner account, 0 if unset. - Allowance { owner: String, spender: String }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InvestmentResponse { - pub token_supply: Uint128, - pub staked_tokens: Coin, - // ratio of staked_tokens / token_supply (or how many native tokens that one derivative token is nominally worth) - pub nominal_value: Decimal, - - /// owner created the contract and takes a cut - pub owner: String, - /// this is how much the owner takes as a cut when someone unbonds - pub exit_tax: Decimal, - /// All tokens are bonded to this validator - pub validator: String, - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, -} diff --git a/contracts/cw20-staking/src/state.rs b/contracts/cw20-staking/src/state.rs deleted file mode 100644 index e179665fd..000000000 --- a/contracts/cw20-staking/src/state.rs +++ /dev/null @@ -1,43 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Addr, Decimal, Uint128}; -use cw_controllers::Claims; -use cw_storage_plus::Item; -use cw_utils::Duration; - -pub const CLAIMS: Claims = Claims::new("claims"); - -/// Investment info is fixed at instantiation, and is used to control the function of the contract -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InvestmentInfo { - /// Owner created the contract and takes a cut - pub owner: Addr, - /// This is the denomination we can stake (and only one we accept for payments) - pub bond_denom: String, - /// This is the unbonding period of the native staking module - /// We need this to only allow claims to be redeemed after the money has arrived - pub unbonding_period: Duration, - /// This is how much the owner takes as a cut when someone unbonds - pub exit_tax: Decimal, - /// All tokens are bonded to this validator - /// FIXME: address validation doesn't work for validator addresses - pub validator: String, - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, -} - -/// Supply is dynamic and tracks the current supply of staked and ERC20 tokens. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)] -pub struct Supply { - /// issued is how many derivative tokens this contract has issued - pub issued: Uint128, - /// bonded is how many native tokens exist bonded to the validator - pub bonded: Uint128, - /// claims is how many tokens need to be reserved paying back those who unbonded - pub claims: Uint128, -} - -pub const INVESTMENT: Item = Item::new("invest"); -pub const TOTAL_SUPPLY: Item = Item::new("total_supply"); From fa8304d2a3a0e5301eae02647f5d7212af4ffb82 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Dec 2021 19:04:43 +0100 Subject: [PATCH 123/631] Regenerate Cargo.lock --- Cargo.lock | 239 ++++------------------------------------------------- 1 file changed, 16 insertions(+), 223 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf9ab4438..63f146579 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,12 +26,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "assert_matches" version = "1.5.0" @@ -65,42 +59,15 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.4.3" @@ -137,7 +104,7 @@ version = "1.0.0-beta3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a380b87642204557629c9b72988c47b55fbfe6d474960adba56b22331504956a" dependencies = [ - "digest 0.9.0", + "digest", "ed25519-zebra", "k256", "rand_core 0.5.1", @@ -210,7 +177,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" dependencies = [ - "generic-array 0.14.4", + "generic-array", "rand_core 0.6.3", "subtle", "zeroize", @@ -222,7 +189,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.4", + "generic-array", "subtle", ] @@ -233,7 +200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", - "digest 0.9.0", + "digest", "rand_core 0.5.1", "subtle", "zeroize", @@ -401,23 +368,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cw20-atomic-swap" -version = "0.11.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "hex 0.3.2", - "schemars", - "serde", - "sha2 0.8.2", - "thiserror", -] - [[package]] name = "cw20-base" version = "0.11.1" @@ -433,42 +383,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw20-bonding" -version = "0.11.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "integer-cbrt", - "integer-sqrt", - "rust_decimal", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-escrow" -version = "0.11.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "cw20-ics20" version = "0.11.1" @@ -484,41 +398,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw20-merkle-airdrop" -version = "0.7.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "hex 0.4.3", - "schemars", - "serde", - "serde_json", - "sha2 0.9.8", - "thiserror", -] - -[[package]] -name = "cw20-staking" -version = "0.11.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "cw3" version = "0.11.1" @@ -631,22 +510,13 @@ dependencies = [ "syn", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -674,10 +544,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409" dependencies = [ "curve25519-dalek", - "hex 0.4.3", + "hex", "rand_core 0.5.1", "serde", - "sha2 0.9.8", + "sha2", "thiserror", ] @@ -695,7 +565,7 @@ checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" dependencies = [ "crypto-bigint", "ff", - "generic-array 0.14.4", + "generic-array", "group", "pkcs8", "rand_core 0.6.3", @@ -703,12 +573,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "ff" version = "0.10.1" @@ -719,15 +583,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -777,12 +632,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "hex" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" - [[package]] name = "hex" version = "0.4.3" @@ -796,25 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "integer-cbrt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151bce4481ba7da831c7d12c32353cc79c73bf79732e343b92786e4cbbb2948c" -dependencies = [ - "num-traits", -] - -[[package]] -name = "integer-sqrt" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" -dependencies = [ - "num-traits", + "digest", ] [[package]] @@ -841,7 +672,7 @@ dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.9.8", + "sha2", ] [[package]] @@ -866,15 +697,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - [[package]] name = "object" version = "0.27.1" @@ -884,12 +706,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -965,17 +781,6 @@ dependencies = [ "getrandom 0.2.3", ] -[[package]] -name = "rust_decimal" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b5a9625a7e6060b23db692facf49082cc78889a7e6ac94a735356ae49db4b0" -dependencies = [ - "arrayvec", - "num-traits", - "serde", -] - [[package]] name = "rustc-demangle" version = "0.1.21" @@ -1069,29 +874,17 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ - "block-buffer 0.9.0", + "block-buffer", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest", + "opaque-debug", ] [[package]] @@ -1100,7 +893,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ - "digest 0.9.0", + "digest", "rand_core 0.6.3", ] @@ -1170,7 +963,7 @@ checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" dependencies = [ "byteorder", "crunchy", - "hex 0.4.3", + "hex", "static_assertions", ] From 59bf5d862aff1b996fbd147aca94a521dc0ac4cf Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 30 Dec 2021 07:55:56 +0100 Subject: [PATCH 124/631] Publish `PrefixBound` --- packages/storage-plus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index e054879cf..0bcbafce0 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -38,6 +38,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}; +pub use prefix::{range_with_prefix, Bound, Prefix, PrefixBound}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; From b7dbdb66a067f8023983ba000dcca25185b9110d Mon Sep 17 00:00:00 2001 From: John Y Date: Thu, 30 Dec 2021 07:22:42 -0500 Subject: [PATCH 125/631] fix readme update coralnet to sandynet-1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 152d92557..062c7fd10 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ many custom contracts. If you don't know what CosmWasm is, please check out [our homepage](https://cosmwasm.com) and [our documentation](https://docs.cosmwasm.com) to get more background. -We are running a [public testnet](https://github.com/CosmWasm/testnets/blob/master/coralnet/README.md) +We are running a [public testnet](https://github.com/CosmWasm/testnets/blob/master/sandynet-1/README.md) you can use to test out any contracts. **Warning** None of these contracts have been audited and no liability is From 5036dce6a2e47d44b4305404edc7fd75d99a8688 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 26 Dec 2021 14:15:28 +0100 Subject: [PATCH 126/631] Add signed int key benches --- packages/storage-plus/Cargo.toml | 11 ++++ packages/storage-plus/benches/main.rs | 94 +++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 packages/storage-plus/benches/main.rs diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 9eefb2040..bf5172df1 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -13,7 +13,18 @@ documentation = "https://docs.cosmwasm.com" default = ["iterator"] iterator = ["cosmwasm-std/iterator"] +[lib] +# See https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options +bench = false + [dependencies] cosmwasm-std = { version = "1.0.0-beta3", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } + +[dev-dependencies] +criterion = { version = "0.3", features = [ "html_reports" ] } + +[[bench]] +name = "main" +harness = false \ No newline at end of file diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs new file mode 100644 index 000000000..cd9bca200 --- /dev/null +++ b/packages/storage-plus/benches/main.rs @@ -0,0 +1,94 @@ +use std::mem; +use std::time::Duration; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use cw_storage_plus::CwIntKey; + +fn bench_signed_int_key(c: &mut Criterion) { + let mut group = c.benchmark_group("Signed int keys"); + + let k: i32 = 0x42434445; + type Buf = [u8; mem::size_of::()]; + + group.bench_function("i32 to_cw_bytes: xored (u32) + to_be_bytes", |b| { + #[inline] + fn to_cw_bytes(value: &i32) -> Buf { + (*value as u32 ^ i32::MIN as u32).to_be_bytes() + } + + assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); + assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); + assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + + b.iter(|| { + black_box(to_cw_bytes(&k)); + }); + }); + + group.bench_function("i32 to_cw_bytes: xored (u128) + to_be_bytes", |b| { + #[inline] + fn to_cw_bytes(value: &i32) -> Buf { + ((*value as u128 ^ i32::MIN as u128) as i32).to_be_bytes() + } + + assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); + assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); + assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + + b.iter(|| { + black_box(to_cw_bytes(&k)); + }); + }); + + group.bench_function("i32 to_cw_bytes: mut to_be_bytes + xor", |b| { + #[inline] + fn to_cw_bytes(value: &i32) -> Buf { + let mut buf = i32::to_be_bytes(*value); + buf[0] ^= 0x80; + buf + } + + assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); + assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); + assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + + b.iter(|| { + black_box(to_cw_bytes(&k)); + }); + }); + + group.bench_function("i32 to_cw_bytes: branching plus / minus", |b| { + #[inline] + fn to_cw_bytes(value: &i32) -> Buf { + if value >= &0i32 { + (*value as u32 - i32::MIN as u32).to_be_bytes() + } else { + (*value as u32 + i32::MIN as u32).to_be_bytes() + } + } + + assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); + assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); + assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + + b.iter(|| { + black_box(to_cw_bytes(&k)); + }); + }); + + group.finish(); +} + +fn make_config() -> Criterion { + Criterion::default() + .without_plots() + .measurement_time(Duration::new(10, 0)) + .sample_size(12) + .configure_from_args() +} + +criterion_group!( + name = signed_int_key; + config = make_config(); + targets = bench_signed_int_key +); +criterion_main!(signed_int_key); From 9d10ba13f3d89b16e412fecdefb8464e0153a496 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 26 Dec 2021 14:26:18 +0100 Subject: [PATCH 127/631] Use random values for signed int key benches --- packages/storage-plus/Cargo.toml | 1 + packages/storage-plus/benches/main.rs | 47 ++++++++++++++++++--------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index bf5172df1..d2370031d 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -24,6 +24,7 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] criterion = { version = "0.3", features = [ "html_reports" ] } +rand = "0.8" [[bench]] name = "main" diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index cd9bca200..9b4c41cc1 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -1,12 +1,23 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +use rand::Rng; use std::mem; use std::time::Duration; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; + use cw_storage_plus::CwIntKey; fn bench_signed_int_key(c: &mut Criterion) { let mut group = c.benchmark_group("Signed int keys"); - let k: i32 = 0x42434445; + fn k() -> i32 { + // let k: i32 = 0x42434445; + // k + let r = rand::thread_rng().gen_range(i32::MIN..i32::MAX); + r + } + // For the asserts + let k_check = k(); + type Buf = [u8; mem::size_of::()]; group.bench_function("i32 to_cw_bytes: xored (u32) + to_be_bytes", |b| { @@ -16,11 +27,12 @@ fn bench_signed_int_key(c: &mut Criterion) { } assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); - assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); + assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&k())); + black_box(to_cw_bytes(&-k())); }); }); @@ -31,11 +43,12 @@ fn bench_signed_int_key(c: &mut Criterion) { } assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); - assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); + assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&k())); + black_box(to_cw_bytes(&-k())); }); }); @@ -48,11 +61,12 @@ fn bench_signed_int_key(c: &mut Criterion) { } assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); - assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); + assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&k())); + black_box(to_cw_bytes(&-k())); }); }); @@ -67,11 +81,12 @@ fn bench_signed_int_key(c: &mut Criterion) { } assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k), i32::to_cw_bytes(&k)); - assert_eq!(to_cw_bytes(&-k), i32::to_cw_bytes(&-k)); + assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); + assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&k())); + black_box(to_cw_bytes(&-k())); }); }); @@ -81,8 +96,8 @@ fn bench_signed_int_key(c: &mut Criterion) { fn make_config() -> Criterion { Criterion::default() .without_plots() - .measurement_time(Duration::new(10, 0)) - .sample_size(12) + .measurement_time(Duration::new(5, 0)) + .sample_size(10) .configure_from_args() } From 384a929d08266a249c64cdda5dab2c5fdd389d1e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 1 Jan 2022 15:00:15 +0100 Subject: [PATCH 128/631] Update lock file --- Cargo.lock | 516 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 515 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 63f146579..e241537d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -59,6 +70,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "block-buffer" version = "0.9.0" @@ -68,6 +85,24 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + [[package]] name = "byteorder" version = "1.4.3" @@ -80,6 +115,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cast" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" +dependencies = [ + "rustc_version", +] + [[package]] name = "cc" version = "1.0.72" @@ -92,6 +136,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + [[package]] name = "const-oid" version = "0.6.2" @@ -165,6 +220,86 @@ dependencies = [ "libc", ] +[[package]] +name = "criterion" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -193,6 +328,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "csv" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +dependencies = [ + "bstr", + "csv-core", + "itoa 0.4.8", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -240,6 +397,8 @@ name = "cw-storage-plus" version = "0.11.1" dependencies = [ "cosmwasm-std", + "criterion", + "rand", "schemars", "serde", ] @@ -632,6 +791,21 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -657,12 +831,27 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "itoa" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "k256" version = "0.9.6" @@ -675,18 +864,42 @@ dependencies = [ "sha2", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -697,6 +910,25 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.27.1" @@ -706,6 +938,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -722,6 +960,40 @@ dependencies = [ "spki", ] +[[package]] +name = "plotters" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" + +[[package]] +name = "plotters-svg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "proc-macro2" version = "1.0.34" @@ -763,6 +1035,28 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.3", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -781,18 +1075,91 @@ dependencies = [ "getrandom 0.2.3", ] +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "rustc-demangle" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schemars" version = "0.8.8" @@ -817,6 +1184,12 @@ dependencies = [ "syn", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "semver" version = "1.0.4" @@ -841,6 +1214,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.132" @@ -869,7 +1252,7 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -929,6 +1312,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.30" @@ -949,6 +1341,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "typenum" version = "1.14.0" @@ -967,6 +1369,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -979,6 +1387,17 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -991,6 +1410,101 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "zeroize" version = "1.4.3" From 1c807cbbe19626d7917250dc4b2959742353169a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 1 Jan 2022 15:00:33 +0100 Subject: [PATCH 129/631] Add unsigned bench for reference Use same value for positive/negative calls --- packages/storage-plus/benches/main.rs | 60 +++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index 9b4c41cc1..761bb7ce3 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -31,8 +31,9 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k())); - black_box(to_cw_bytes(&-k())); + let k = k(); + black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&-k)); }); }); @@ -47,8 +48,9 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k())); - black_box(to_cw_bytes(&-k())); + let k = k(); + black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&-k)); }); }); @@ -65,8 +67,9 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k())); - black_box(to_cw_bytes(&-k())); + let k = k(); + black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&-k)); }); }); @@ -85,8 +88,42 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); b.iter(|| { - black_box(to_cw_bytes(&k())); - black_box(to_cw_bytes(&-k())); + let k = k(); + black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&-k)); + }); + }); + + group.finish(); +} + +fn bench_unsigned_int_key(c: &mut Criterion) { + let mut group = c.benchmark_group("Unsigned int keys"); + + fn k() -> u32 { + // let k: u32 = 0x42434445; + // k + let r = rand::thread_rng().gen_range(u32::MIN..u32::MAX); + r + } + // For the asserts + let k_check = k(); + + type Buf = [u8; mem::size_of::()]; + + group.bench_function("u32 to_cw_bytes", |b| { + #[inline] + fn to_cw_bytes(value: &u32) -> Buf { + value.to_be_bytes() + } + + assert_eq!(to_cw_bytes(&0), u32::to_cw_bytes(&0)); + assert_eq!(to_cw_bytes(&k_check), u32::to_cw_bytes(&k_check)); + + b.iter(|| { + let k = k(); + black_box(to_cw_bytes(&k)); + black_box(to_cw_bytes(&k)); // twice for comparability }); }); @@ -106,4 +143,9 @@ criterion_group!( config = make_config(); targets = bench_signed_int_key ); -criterion_main!(signed_int_key); +criterion_group!( + name = unsigned_int_key; + config = make_config(); + targets = bench_unsigned_int_key +); +criterion_main!(signed_int_key, unsigned_int_key); From 24f7aad3eebc889ce36fab881c45f9493eee4b95 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 3 Jan 2022 08:36:48 +0100 Subject: [PATCH 130/631] Add benchmarking job to CI --- .circleci/config.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index b1ac2aa51..e0f17176b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,18 @@ workflows: - package_storage_plus - lint - wasm-build + - benchmarking: + requires: + - package_storage_plus + filters: + branches: + only: + # Long living branches + - main + - /^[0-9]+\.[0-9]+$/ + # 👇Add your branch here if benchmarking matters to your work + - benchmarking + - signed-int-key-bench deploy: jobs: - build_and_upload_contracts: @@ -662,6 +674,29 @@ jobs: - target key: cargocache-v2-storage-plus:1.53.0-{{ checksum "~/project/Cargo.lock" }} + benchmarking: + docker: + - image: rust:1.53.0 + environment: + RUST_BACKTRACE: 1 + steps: + - checkout + - run: + name: Version information (default; stable) + command: rustc --version && cargo --version + - restore_cache: + keys: + - cargocache-v2-benchmarking-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} + - run: + name: Run storage-plus benchmarks + working_directory: ~/project/packages/storage-plus + command: cargo bench -- --color never --save-baseline + - save_cache: + paths: + - /usr/local/cargo/registry + - target + key: cargocache-v2-benchmarking-rust:1.53.0-{{ 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: docker: From d5d255cf09c26fa647f118db2864e8274fc75fe5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 3 Jan 2022 08:39:48 +0100 Subject: [PATCH 131/631] Fix clippy warnings --- packages/storage-plus/benches/main.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index 761bb7ce3..cd02624c5 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -12,8 +12,7 @@ fn bench_signed_int_key(c: &mut Criterion) { fn k() -> i32 { // let k: i32 = 0x42434445; // k - let r = rand::thread_rng().gen_range(i32::MIN..i32::MAX); - r + rand::thread_rng().gen_range(i32::MIN..i32::MAX) } // For the asserts let k_check = k(); @@ -103,8 +102,7 @@ fn bench_unsigned_int_key(c: &mut Criterion) { fn k() -> u32 { // let k: u32 = 0x42434445; // k - let r = rand::thread_rng().gen_range(u32::MIN..u32::MAX); - r + rand::thread_rng().gen_range(u32::MIN..u32::MAX) } // For the asserts let k_check = k(); From a1cab57563ab0952c14e6e0dd0e17bc13ce08c8d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 3 Jan 2022 08:46:36 +0100 Subject: [PATCH 132/631] Fix checkout --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e0f17176b..3ecd7a00c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -680,7 +680,8 @@ jobs: environment: RUST_BACKTRACE: 1 steps: - - checkout + - checkout: + path: ~/project - run: name: Version information (default; stable) command: rustc --version && cargo --version From 6c22e89acd85c758ca81a1ec067479aee1bdce9f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 3 Jan 2022 11:23:47 +0100 Subject: [PATCH 133/631] Remove unneeded branches from benchmarking --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3ecd7a00c..bccf2c4b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,10 +33,7 @@ workflows: only: # Long living branches - main - - /^[0-9]+\.[0-9]+$/ # 👇Add your branch here if benchmarking matters to your work - - benchmarking - - signed-int-key-bench deploy: jobs: - build_and_upload_contracts: From 6b595b524a1ee7a3c64deb6754727774e15e67e8 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 3 Jan 2022 13:29:55 +0100 Subject: [PATCH 134/631] Remove IntKey and TimestampKey with all surrounding implementations --- packages/storage-plus/src/de.rs | 127 +------------------ packages/storage-plus/src/keys.rs | 194 +----------------------------- packages/storage-plus/src/lib.rs | 9 +- 3 files changed, 7 insertions(+), 323 deletions(-) diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 60f6fcb57..c1b13889f 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -1,13 +1,9 @@ -// TODO: Remove along with IntKey -#![allow(deprecated)] - use std::array::TryFromSliceError; use std::convert::TryInto; use cosmwasm_std::{Addr, StdError, StdResult}; use crate::int_key::CwIntKey; -use crate::keys::{IntKey, TimestampKey}; pub trait KeyDeserialize { type Output: Sized; @@ -116,31 +112,6 @@ macro_rules! integer_de { integer_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); -macro_rules! intkey_de { - (for $($t:ty),+) => { - $(impl KeyDeserialize for IntKey<$t> { - type Output = $t; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(<$t>::from_cw_bytes(value.as_slice().try_into() - .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) - } - })* - } -} - -intkey_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); - -impl KeyDeserialize for TimestampKey { - type Output = u64; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - >::from_vec(value) - } -} - fn parse_length(value: &[u8]) -> StdResult { Ok(u16::from_be_bytes( value @@ -183,7 +154,7 @@ impl KeyDeserialize for #[cfg(test)] mod test { use super::*; - use crate::{PrimaryKey, U32Key}; + use crate::PrimaryKey; const BYTES: &[u8] = b"Hello"; const STRING: &str = "Hello"; @@ -278,96 +249,6 @@ mod test { ); } - #[test] - fn deserialize_integer_works() { - assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); - assert_eq!(>::from_slice(&[127]).unwrap(), -1i8); - assert_eq!(>::from_slice(&[128]).unwrap(), 0i8); - - assert_eq!(>::from_slice(&[1, 0]).unwrap(), 256u16); - assert_eq!(>::from_slice(&[128, 0]).unwrap(), 0i16); - assert_eq!(>::from_slice(&[127, 255]).unwrap(), -1i16); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0]).unwrap(), - 16777216u32 - ); - assert_eq!(>::from_slice(&[128, 0, 0, 0]).unwrap(), 0i32); - assert_eq!( - >::from_slice(&[127, 255, 255, 255]).unwrap(), - -1i32 - ); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 72057594037927936u64 - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 0i64 - ); - assert_eq!( - >::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), - -1i64 - ); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 1329227995784915872903807060280344576u128 - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - .unwrap(), - 0i128 - ); - assert_eq!( - >::from_slice(&[ - 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - -1i128 - ); - assert_eq!( - >::from_slice(&[ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - 170141183460469231731687303715884105727i128, - ); - } - - #[test] - fn deserialize_broken_integer_errs() { - // One byte less fails - assert!(matches!( - >::from_slice(&[1]).err(), - Some(StdError::GenericErr { .. }) - )); - - // More bytes fails too - assert!(matches!( - >::from_slice(&[1, 2]).err(), - Some(StdError::GenericErr { .. }) - )); - } - - #[test] - fn deserialize_timestamp_works() { - assert_eq!( - ::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 72057594037927936 - ); - } - - #[test] - fn deserialize_broken_timestamp_errs() { - // More bytes fails - assert!(matches!( - ::from_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9]).err(), - Some(StdError::GenericErr { .. }) - )); - } - #[test] fn deserialize_tuple_works() { assert_eq!( @@ -379,10 +260,8 @@ mod test { #[test] fn deserialize_triple_works() { assert_eq!( - <(&[u8], U32Key, &str)>::from_slice( - (BYTES, U32Key::new(1234), STRING).joined_key().as_slice() - ) - .unwrap(), + <(&[u8], u32, &str)>::from_slice((BYTES, 1234u32, STRING).joined_key().as_slice()) + .unwrap(), (BYTES.to_vec(), 1234, STRING.to_string()) ); } diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 63bedba2e..e4240abb1 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -1,13 +1,8 @@ -// TODO: Remove along with IntKey -#![allow(deprecated)] - -use cosmwasm_std::{Addr, Timestamp}; -use std::marker::PhantomData; +use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; use crate::int_key::CwIntKey; -use crate::Endian; #[derive(Debug)] pub enum Key<'a> { @@ -305,153 +300,10 @@ macro_rules! integer_prefix { integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); -// this auto-implements PrimaryKey for all the IntKey types -impl<'a, T: Endian + Clone> PrimaryKey<'a> for IntKey -where - IntKey: KeyDeserialize, -{ - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - self.wrapped.key() - } -} - -// this auto-implements Prefixer for all the IntKey types -impl<'a, T: Endian> Prefixer<'a> for IntKey { - fn prefix(&self) -> Vec { - self.wrapped.prefix() - } -} - -#[deprecated(note = "It is suggested to use `u8` as key type instead of the `U8Key` wrapper")] -pub type U8Key = IntKey; -#[deprecated(note = "It is suggested to use `u16` as key type instead of the `U16Key` wrapper")] -pub type U16Key = IntKey; -#[deprecated(note = "It is suggested to use `u32` as key type instead of the `U32Key` wrapper")] -pub type U32Key = IntKey; -#[deprecated(note = "It is suggested to use `u64` as key type instead of the `U64Key` wrapper")] -pub type U64Key = IntKey; -#[deprecated(note = "Consider using 64-bit keys instead of the `U128Key` wrapper")] -pub type U128Key = IntKey; - -#[deprecated(note = "It is suggested to use `i8` as key type instead of the `I8Key` wrapper")] -pub type I8Key = IntKey; -#[deprecated(note = "It is suggested to use `i16` as key type instead of the `I16Key` wrapper")] -pub type I16Key = IntKey; -#[deprecated(note = "It is suggested to use `i32` as key type instead of the `I32Key` wrapper")] -pub type I32Key = IntKey; -#[deprecated(note = "It is suggested to use `i64` as key type instead of the `I64Key` wrapper")] -pub type I64Key = IntKey; -#[deprecated(note = "Consider using 64-bit keys instead of the `I128Key` wrapper")] -pub type I128Key = IntKey; - -/// It will cast one-particular int type into a Key via Vec, ensuring you don't mix up u32 and u64 -/// You can use new or the from/into pair to build a key from an int: -/// -/// let k = U64Key::new(12345); -/// let k = U32Key::from(12345); -/// let k: U16Key = 12345.into(); -#[deprecated(note = "It is suggested to use naked int types instead of IntKey wrapper")] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct IntKey { - pub wrapped: Vec, - pub data: PhantomData, -} - -impl IntKey { - pub fn new(val: T) -> Self { - IntKey { - wrapped: val.to_cw_bytes().into(), - data: PhantomData, - } - } -} - -impl From for IntKey { - fn from(val: T) -> Self { - IntKey::new(val) - } -} - -impl From> for IntKey { - fn from(wrap: Vec) -> Self { - // TODO: Consider properly handling case, when `wrap` has length not conforming for the - // wrapped integer type. - IntKey { - wrapped: wrap, - data: PhantomData, - } - } -} - -impl From> for Vec { - fn from(k: IntKey) -> Vec { - k.wrapped - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct TimestampKey(U64Key); - -impl TimestampKey { - pub fn new(ts: Timestamp) -> Self { - Self(ts.nanos().into()) - } -} - -impl<'a> PrimaryKey<'a> for TimestampKey { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - self.0.key() - } -} - -impl<'a> Prefixer<'a> for TimestampKey { - fn prefix(&self) -> Vec { - self.0.prefix() - } -} - -impl From> for TimestampKey { - fn from(val: Vec) -> Self { - Self(val.into()) - } -} - -impl From for TimestampKey { - fn from(val: Timestamp) -> Self { - Self::new(val) - } -} - #[cfg(test)] mod test { use super::*; - #[test] - fn u64key_works() { - let k: U64Key = 134u64.into(); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(134u64.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn u32key_works() { - let k: U32Key = 4242u32.into(); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242u32.to_cw_bytes(), path[0].as_ref()); - } - #[test] fn naked_8key_works() { let k: u8 = 42u8; @@ -549,22 +401,9 @@ mod test { assert_eq!(path, vec!["foo".as_bytes(), b"bar"],); } - #[test] - fn composite_int_key() { - // Note we don't spec the int types (u32, u64) on the right, - // just the keys they convert into - let k: (U32Key, U64Key) = (123.into(), 87654.into()); - let path = k.key(); - assert_eq!(2, path.len()); - assert_eq!(4, path[0].as_ref().len()); - assert_eq!(8, path[1].as_ref().len()); - assert_eq!(path[0].as_ref(), 123u32.to_cw_bytes()); - assert_eq!(path[1].as_ref(), 87654u64.to_cw_bytes()); - } - #[test] fn naked_composite_int_key() { - let k: (u32, U64Key) = (123, 87654.into()); + let k: (u32, u64) = (123, 87654); let path = k.key(); assert_eq!(2, path.len()); assert_eq!(4, path[0].as_ref().len()); @@ -589,35 +428,6 @@ mod test { assert_eq!(dir, vec![first, b"bar"]); } - #[test] - fn proper_prefixes() { - let simple: &str = "hello"; - assert_eq!(simple.prefix().len(), 1); - assert_eq!(simple.prefix()[0].as_ref(), b"hello"); - - let pair: (U32Key, &[u8]) = (12345.into(), b"random"); - let one: Vec = vec![0, 0, 48, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - - let triple: (&str, U32Key, &[u8]) = ("begin", 12345.into(), b"end"); - let one: Vec = b"begin".to_vec(); - let two: Vec = vec![0, 0, 48, 57]; - let three: Vec = b"end".to_vec(); - assert_eq!( - triple.prefix(), - vec![one.as_slice(), two.as_slice(), three.as_slice()] - ); - - // same works with owned variants (&str -> String, &[u8] -> Vec) - let owned_triple: (String, U32Key, Vec) = - ("begin".to_string(), 12345.into(), b"end".to_vec()); - assert_eq!( - owned_triple.prefix(), - vec![one.as_slice(), two.as_slice(), three.as_slice()] - ); - } - #[test] fn naked_8bit_prefixes() { let pair: (u8, &[u8]) = (123, b"random"); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 0bcbafce0..ff8e508b9 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -26,14 +26,9 @@ pub use indexes::MultiIndex; pub use indexes::UniqueIndex; #[cfg(feature = "iterator")] pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; -pub use item::Item; -// TODO: Remove along with `IntKey` -#[allow(deprecated)] -pub use keys::{I128Key, I16Key, I32Key, I64Key, I8Key}; -// TODO: Remove along with `IntKey` pub use int_key::CwIntKey; -#[allow(deprecated)] -pub use keys::{Key, Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key, U8Key}; +pub use item::Item; +pub use keys::{Key, Prefixer, PrimaryKey}; pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; From ac89c423ed6f83246ae9197bdce19551e2122a20 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 3 Jan 2022 13:51:07 +0100 Subject: [PATCH 135/631] Rename CwIntKey into IntKey --- packages/storage-plus/benches/main.rs | 2 +- packages/storage-plus/src/de.rs | 2 +- packages/storage-plus/src/int_key.rs | 7 +++---- packages/storage-plus/src/keys.rs | 2 +- packages/storage-plus/src/lib.rs | 2 +- packages/storage-plus/src/map.rs | 2 +- packages/storage-plus/src/prefix.rs | 6 +++--- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index cd02624c5..021deac65 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -4,7 +4,7 @@ use rand::Rng; use std::mem; use std::time::Duration; -use cw_storage_plus::CwIntKey; +use cw_storage_plus::IntKey; fn bench_signed_int_key(c: &mut Criterion) { let mut group = c.benchmark_group("Signed int keys"); diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index c1b13889f..046d8b9cb 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use cosmwasm_std::{Addr, StdError, StdResult}; -use crate::int_key::CwIntKey; +use crate::int_key::IntKey; pub trait KeyDeserialize { type Output: Sized; diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 7f7713369..0292674a2 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -4,8 +4,7 @@ use std::mem; /// but "sign-flipped" (xored msb) big-endian bytes for signed ints. /// /// So that the representation of signed integers is in the right lexicographical order. -// TODO: Rename to `IntKey` after deprecating current `IntKey` (https://github.com/CosmWasm/cw-plus/issues/570) -pub trait CwIntKey: Sized + Copy { +pub trait IntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; fn to_cw_bytes(&self) -> Self::Buf; @@ -14,7 +13,7 @@ pub trait CwIntKey: Sized + Copy { macro_rules! cw_uint_keys { (for $($t:ty),+) => { - $(impl CwIntKey for $t { + $(impl IntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] @@ -34,7 +33,7 @@ cw_uint_keys!(for u8, u16, u32, u64, u128); macro_rules! cw_int_keys { (for $($t:ty, $ut:ty),+) => { - $(impl CwIntKey for $t { + $(impl IntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index e4240abb1..2fd90e446 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -2,7 +2,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; -use crate::int_key::CwIntKey; +use crate::int_key::IntKey; #[derive(Debug)] pub enum Key<'a> { diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index ff8e508b9..9b5714994 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -26,7 +26,7 @@ pub use indexes::MultiIndex; pub use indexes::UniqueIndex; #[cfg(feature = "iterator")] pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; -pub use int_key::CwIntKey; +pub use int_key::IntKey; pub use item::Item; pub use keys::{Key, Prefixer, PrimaryKey}; pub use keys_old::IntKeyOld; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 94d78bdcd..cf784902a 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -254,7 +254,7 @@ mod test { #[cfg(feature = "iterator")] use cosmwasm_std::{Order, StdResult}; - use crate::int_key::CwIntKey; + use crate::int_key::IntKey; use crate::keys_old::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 38e4b7c78..4b48c69c2 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -8,7 +8,7 @@ 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::int_key::IntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::Key; use crate::{Endian, Prefixer}; @@ -35,12 +35,12 @@ impl Bound { } /// Turns an int, like Option into an inclusive bound - pub fn inclusive_int(limit: T) -> Self { + pub fn inclusive_int(limit: T) -> Self { Bound::Inclusive(limit.to_cw_bytes().into()) } /// Turns an int, like Option into an exclusive bound - pub fn exclusive_int(limit: T) -> Self { + pub fn exclusive_int(limit: T) -> Self { Bound::Exclusive(limit.to_cw_bytes().into()) } } From 142ced5a7f9403830ee6bc2ee7891dde1fc8c5e5 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 3 Jan 2022 14:42:39 +0100 Subject: [PATCH 136/631] Revert "Rename CwIntKey into IntKey" This reverts commit ac89c423ed6f83246ae9197bdce19551e2122a20. --- packages/storage-plus/benches/main.rs | 2 +- packages/storage-plus/src/de.rs | 2 +- packages/storage-plus/src/int_key.rs | 7 ++++--- packages/storage-plus/src/keys.rs | 2 +- packages/storage-plus/src/lib.rs | 2 +- packages/storage-plus/src/map.rs | 2 +- packages/storage-plus/src/prefix.rs | 6 +++--- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index 021deac65..cd02624c5 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -4,7 +4,7 @@ use rand::Rng; use std::mem; use std::time::Duration; -use cw_storage_plus::IntKey; +use cw_storage_plus::CwIntKey; fn bench_signed_int_key(c: &mut Criterion) { let mut group = c.benchmark_group("Signed int keys"); diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index 046d8b9cb..c1b13889f 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use cosmwasm_std::{Addr, StdError, StdResult}; -use crate::int_key::IntKey; +use crate::int_key::CwIntKey; pub trait KeyDeserialize { type Output: Sized; diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 0292674a2..7f7713369 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -4,7 +4,8 @@ use std::mem; /// but "sign-flipped" (xored msb) big-endian bytes for signed ints. /// /// So that the representation of signed integers is in the right lexicographical order. -pub trait IntKey: Sized + Copy { +// TODO: Rename to `IntKey` after deprecating current `IntKey` (https://github.com/CosmWasm/cw-plus/issues/570) +pub trait CwIntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; fn to_cw_bytes(&self) -> Self::Buf; @@ -13,7 +14,7 @@ pub trait IntKey: Sized + Copy { macro_rules! cw_uint_keys { (for $($t:ty),+) => { - $(impl IntKey for $t { + $(impl CwIntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] @@ -33,7 +34,7 @@ cw_uint_keys!(for u8, u16, u32, u64, u128); macro_rules! cw_int_keys { (for $($t:ty, $ut:ty),+) => { - $(impl IntKey for $t { + $(impl CwIntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 2fd90e446..e4240abb1 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -2,7 +2,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; -use crate::int_key::IntKey; +use crate::int_key::CwIntKey; #[derive(Debug)] pub enum Key<'a> { diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 9b5714994..ff8e508b9 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -26,7 +26,7 @@ pub use indexes::MultiIndex; pub use indexes::UniqueIndex; #[cfg(feature = "iterator")] pub use indexes::{index_string, index_string_tuple, index_triple, index_tuple, Index}; -pub use int_key::IntKey; +pub use int_key::CwIntKey; pub use item::Item; pub use keys::{Key, Prefixer, PrimaryKey}; pub use keys_old::IntKeyOld; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index cf784902a..94d78bdcd 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -254,7 +254,7 @@ mod test { #[cfg(feature = "iterator")] use cosmwasm_std::{Order, StdResult}; - use crate::int_key::IntKey; + use crate::int_key::CwIntKey; use crate::keys_old::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 4b48c69c2..38e4b7c78 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -8,7 +8,7 @@ use std::ops::Deref; use crate::de::KeyDeserialize; use crate::helpers::{namespaces_with_key, nested_namespaces_with_key}; -use crate::int_key::IntKey; +use crate::int_key::CwIntKey; use crate::iter_helpers::{concat, deserialize_kv, deserialize_v, trim}; use crate::keys::Key; use crate::{Endian, Prefixer}; @@ -35,12 +35,12 @@ impl Bound { } /// Turns an int, like Option into an inclusive bound - pub fn inclusive_int(limit: T) -> Self { + pub fn inclusive_int(limit: T) -> Self { Bound::Inclusive(limit.to_cw_bytes().into()) } /// Turns an int, like Option into an exclusive bound - pub fn exclusive_int(limit: T) -> Self { + pub fn exclusive_int(limit: T) -> Self { Bound::Exclusive(limit.to_cw_bytes().into()) } } From 582e47e4a251b050e3de5977e90feafaa05ef5ca Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 3 Jan 2022 19:09:56 +0100 Subject: [PATCH 137/631] multitest: add a contract that tests WasmMsg calls --- packages/multi-test/src/contracts.rs | 2 +- .../multi-test/src/test_helpers/contracts.rs | 1 + .../src/test_helpers/contracts/caller.rs | 40 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/multi-test/src/test_helpers/contracts/caller.rs diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index bf88b1158..8aca6173b 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -342,7 +342,7 @@ where (self.execute_fn)(deps, env, info.clone(), msg.clone()) .map_err(|err| anyhow!("{}", err)) .context(format!( - r#"Contract returned an error on execute + r#"aContract returned an error on execute Contract address: {} Message sender: {} Funds: {:?} diff --git a/packages/multi-test/src/test_helpers/contracts.rs b/packages/multi-test/src/test_helpers/contracts.rs index 8be3e8674..68babbf84 100644 --- a/packages/multi-test/src/test_helpers/contracts.rs +++ b/packages/multi-test/src/test_helpers/contracts.rs @@ -1,5 +1,6 @@ //! Module for simple contracts to be used in tests +pub mod caller; pub mod echo; pub mod error; pub mod hackatom; diff --git a/packages/multi-test/src/test_helpers/contracts/caller.rs b/packages/multi-test/src/test_helpers/contracts/caller.rs new file mode 100644 index 000000000..92367a3de --- /dev/null +++ b/packages/multi-test/src/test_helpers/contracts/caller.rs @@ -0,0 +1,40 @@ +use std::fmt; + +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, SubMsg, WasmMsg}; +use schemars::JsonSchema; + +use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; + +fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: EmptyMsg, +) -> Result { + Ok(Response::default()) +} + +fn execute( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: WasmMsg, +) -> Result { + let message = SubMsg::new(msg); + + Ok(Response::new().add_submessage(message)) +} + +fn query(_deps: Deps, _env: Env, _msg: EmptyMsg) -> Result { + Err(StdError::generic_err( + "query not implemented for the `caller` contract", + )) +} + +pub fn contract() -> Box> +where + C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, +{ + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} From 0291e82f1ffde063cdbd1917fe8a392eab690755 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 11:22:36 +0100 Subject: [PATCH 138/631] multitest: add tests for contract errors --- packages/multi-test/src/app.rs | 132 +++++++++++++++++- packages/multi-test/src/contracts.rs | 7 +- .../src/test_helpers/contracts/error.rs | 19 ++- packages/multi-test/src/wasm.rs | 2 +- 4 files changed, 152 insertions(+), 8 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 7af9792e2..01a1ddfa4 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -947,7 +947,7 @@ mod test { }; use crate::error::Error; - use crate::test_helpers::contracts::{echo, hackatom, payout, reflect}; + use crate::test_helpers::contracts::{caller, echo, error, hackatom, payout, reflect}; use crate::test_helpers::{CustomMsg, EmptyMsg}; use crate::transactions::StorageTransaction; @@ -2580,4 +2580,134 @@ mod test { assert_eq!(exec_res.data, Some(Binary::from(b"hello"))); } } + + mod errors { + use super::*; + + #[test] + fn simple_call() { + let owner = Addr::unchecked("owner"); + let mut app = App::default(); + + // set up contract + let code_id = app.store_code(error::contract(true)); + let msg = EmptyMsg {}; + let contract_addr = app + .instantiate_contract(code_id, owner, &msg, &[], "error", None) + .unwrap(); + + // execute should error + let err = app + .execute_contract(Addr::unchecked("random"), contract_addr.clone(), &msg, &[]) + .unwrap_err(); + let source: &StdError = err.downcast_ref().unwrap(); + if let StdError::GenericErr { msg } = source { + assert_eq!(msg, "Handle failed"); + } else { + panic!("wrong StdError variant"); + } + } + + // #[test] + // fn simple_call_gives_one_context_layer() { + // let owner = Addr::unchecked("owner"); + // let mut app = App::default(); + + // let error_code_id = app.store_code(error::contract(true)); + + // // set up contract + // let msg = EmptyMsg {}; + // let error_addr = app + // .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) + // .unwrap(); + + // // execute should error + // let err = app + // .execute_contract(Addr::unchecked("random"), error_addr.clone(), &msg, &[]) + // .unwrap(); + // //let source = err.source().unwrap(); + // //let foo: &StdError = source.downcast_ref().unwrap(); + // //assert_eq!(source.to_string(), "aContract returned an error on execute\nContract address: Contract #0\nMessage sender: random\nFunds: []\nMessage dump:\nEmptyMsg\n"); + // } + + #[test] + fn nested_call() { + let owner = Addr::unchecked("owner"); + let mut app = App::default(); + + let error_code_id = app.store_code(error::contract(true)); + let caller_code_id = app.store_code(caller::contract()); + + // set up contracts + let msg = EmptyMsg {}; + let caller_addr = app + .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) + .unwrap(); + let error_addr = app + .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) + .unwrap(); + + // execute should error + let msg = WasmMsg::Execute { + contract_addr: error_addr.into(), + msg: to_binary(&EmptyMsg {}).unwrap(), + funds: vec![], + }; + let err = app + .execute_contract(Addr::unchecked("random"), caller_addr.clone(), &msg, &[]) + .unwrap_err(); + + // we can downcast to get the original error + let source: &StdError = err.downcast_ref().unwrap(); + if let StdError::GenericErr { msg } = source { + assert_eq!(msg, "Handle failed"); + } else { + panic!("wrong StdError variant"); + } + } + + #[test] + fn double_nested_call() { + let owner = Addr::unchecked("owner"); + let mut app = App::default(); + + let error_code_id = app.store_code(error::contract(true)); + let caller_code_id = app.store_code(caller::contract()); + + // set up contracts + let msg = EmptyMsg {}; + let caller_addr1 = app + .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) + .unwrap(); + let caller_addr2 = app + .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) + .unwrap(); + let error_addr = app + .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) + .unwrap(); + + // caller1 calls caller2, caller2 calls error + let msg = WasmMsg::Execute { + contract_addr: caller_addr2.into(), + msg: to_binary(&WasmMsg::Execute { + contract_addr: error_addr.into(), + msg: to_binary(&EmptyMsg {}).unwrap(), + funds: vec![], + }) + .unwrap(), + funds: vec![], + }; + let err = app + .execute_contract(Addr::unchecked("random"), caller_addr1.clone(), &msg, &[]) + .unwrap_err(); + + // we can downcast to get the original error + let source: &StdError = err.downcast_ref().unwrap(); + if let StdError::GenericErr { msg } = source { + assert_eq!(msg, "Handle failed"); + } else { + panic!("wrong StdError variant"); + } + } + } } diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 8aca6173b..39101245b 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -1,5 +1,6 @@ use schemars::JsonSchema; use serde::de::DeserializeOwned; +use std::error::Error; use std::fmt::{self, Debug, Display}; use cosmwasm_std::{ @@ -322,7 +323,7 @@ where T3: DeserializeOwned, T4: DeserializeOwned, T6: DeserializeOwned, - E1: Display + Debug + Send + Sync + 'static, + E1: Display + Debug + Send + Sync + Error + 'static, E2: Display + Debug + Send + Sync + 'static, E3: Display + Debug + Send + Sync + 'static, E4: Display + Debug + Send + Sync + 'static, @@ -340,9 +341,9 @@ where let msg: T1 = from_slice(&msg)?; let address = env.contract.address.clone(); (self.execute_fn)(deps, env, info.clone(), msg.clone()) - .map_err(|err| anyhow!("{}", err)) + .map_err(|err| anyhow::Error::from(err)) .context(format!( - r#"aContract returned an error on execute + r#"Contract returned an error on execute Contract address: {} Message sender: {} Funds: {:?} diff --git a/packages/multi-test/src/test_helpers/contracts/error.rs b/packages/multi-test/src/test_helpers/contracts/error.rs index 710484aca..e707e80d6 100644 --- a/packages/multi-test/src/test_helpers/contracts/error.rs +++ b/packages/multi-test/src/test_helpers/contracts/error.rs @@ -5,7 +5,7 @@ use schemars::JsonSchema; use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; -fn instantiate( +fn instantiate_err( _deps: DepsMut, _env: Env, _info: MessageInfo, @@ -14,6 +14,15 @@ fn instantiate( Err(StdError::generic_err("Init failed")) } +fn instantiate_ok( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: EmptyMsg, +) -> Result { + Ok(Response::default()) +} + fn execute( _deps: DepsMut, _env: Env, @@ -27,10 +36,14 @@ fn query(_deps: Deps, _env: Env, _msg: EmptyMsg) -> Result { Err(StdError::generic_err("Query failed")) } -pub fn contract() -> Box> +pub fn contract(instantiable: bool) -> Box> where C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, { - let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + let contract = if instantiable { + ContractWrapper::new_with_empty(execute, instantiate_ok, query) + } else { + ContractWrapper::new_with_empty(execute, instantiate_err, query) + }; Box::new(contract) } diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 1e1ef5872..a0b7c66c6 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -946,7 +946,7 @@ mod test { let mut wasm_storage = MockStorage::new(); let mut keeper = WasmKeeper::new(); let block = mock_env().block; - let code_id = keeper.store_code(error::contract()); + let code_id = keeper.store_code(error::contract(false)); transactional(&mut wasm_storage, |cache, _| { // cannot register contract with unregistered codeId From 2c90217e59945eef0c6a6f8fa6f53e6904e529f4 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 15:05:53 +0100 Subject: [PATCH 139/631] multitest: handle nested error contexts properly --- packages/multi-test/src/app.rs | 36 +++++++++++----------------- packages/multi-test/src/contracts.rs | 11 ++------- packages/multi-test/src/executor.rs | 15 ++---------- packages/multi-test/src/wasm.rs | 13 +++++++--- 4 files changed, 28 insertions(+), 47 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 01a1ddfa4..25c50d312 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2600,35 +2600,19 @@ mod test { let err = app .execute_contract(Addr::unchecked("random"), contract_addr.clone(), &msg, &[]) .unwrap_err(); + + // we should be able to retrieve the original error by downcasting let source: &StdError = err.downcast_ref().unwrap(); if let StdError::GenericErr { msg } = source { assert_eq!(msg, "Handle failed"); } else { panic!("wrong StdError variant"); } - } - - // #[test] - // fn simple_call_gives_one_context_layer() { - // let owner = Addr::unchecked("owner"); - // let mut app = App::default(); - - // let error_code_id = app.store_code(error::contract(true)); - // // set up contract - // let msg = EmptyMsg {}; - // let error_addr = app - // .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) - // .unwrap(); - - // // execute should error - // let err = app - // .execute_contract(Addr::unchecked("random"), error_addr.clone(), &msg, &[]) - // .unwrap(); - // //let source = err.source().unwrap(); - // //let foo: &StdError = source.downcast_ref().unwrap(); - // //assert_eq!(source.to_string(), "aContract returned an error on execute\nContract address: Contract #0\nMessage sender: random\nFunds: []\nMessage dump:\nEmptyMsg\n"); - // } + // we're expecting exactly 3 wrapped errors + // (the original error, execute msg context, WasmMsg context) + assert_eq!(err.chain().count(), 3); + } #[test] fn nested_call() { @@ -2664,6 +2648,10 @@ mod test { } else { panic!("wrong StdError variant"); } + + // we're expecting exactly 4 wrapped errors + // (the original error, execute msg context, 2 WasmMsg contexts) + assert_eq!(err.chain().count(), 4); } #[test] @@ -2708,6 +2696,10 @@ mod test { } else { panic!("wrong StdError variant"); } + + // we're expecting exactly 5 wrapped errors + // (the original error, execute msg context, 3 WasmMsg contexts) + assert_eq!(err.chain().count(), 5); } } } diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 39101245b..1cb04509c 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -339,18 +339,11 @@ where msg: Vec, ) -> AnyResult> { let msg: T1 = from_slice(&msg)?; - let address = env.contract.address.clone(); (self.execute_fn)(deps, env, info.clone(), msg.clone()) .map_err(|err| anyhow::Error::from(err)) .context(format!( - r#"Contract returned an error on execute -Contract address: {} -Message sender: {} -Funds: {:?} -Message dump: -{:?} -"#, - address, info.sender, info.funds, msg, + "Contract returned an error on execute msg:\n{:?}", + msg, )) } diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index 31fe75ee5..0ab199413 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -8,7 +8,7 @@ use schemars::JsonSchema; use serde::Serialize; use utils::{parse_execute_response_data, parse_instantiate_response_data}; -use anyhow::{Context, Result as AnyResult}; +use anyhow::Result as AnyResult; #[derive(Default, Clone, Debug)] pub struct AppResponse { @@ -111,18 +111,7 @@ where msg: binary_msg, funds: send_funds.to_vec(), }; - let mut res = self - .execute(sender.clone(), wrapped_msg.into()) - .context(format!( - r#"Contract returned an error on execute -Contract address: {} -Message sender: {} -Funds: {:?} -Message dump: -{:?} -"#, - contract_addr, sender, send_funds, msg, - ))?; + let mut res = self.execute(sender.clone(), wrapped_msg.into())?; res.data = res .data .and_then(|d| parse_execute_response_data(d.as_slice()).unwrap().data); diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index a0b7c66c6..542c485d0 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -23,7 +23,7 @@ use crate::executor::AppResponse; use crate::transactions::transactional; use cosmwasm_std::testing::mock_wasmd_attr; -use anyhow::{bail, Result as AnyResult}; +use anyhow::{bail, Context, Result as AnyResult}; // TODO: we should import this from cosmwasm-std, but cannot due to non_exhaustive so copy here #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -174,7 +174,11 @@ where sender: Addr, msg: WasmMsg, ) -> AnyResult { - self.execute_wasm(api, storage, router, block, sender, msg) + self.execute_wasm(api, storage, router, block, sender.clone(), msg.clone()) + .context(format!( + "error executing WasmMsg:\nsender: {}\n{:?}", + sender, msg + )) } fn sudo( @@ -297,7 +301,10 @@ where )?; // then call the contract - let info = MessageInfo { sender, funds }; + let info = MessageInfo { + sender: sender.clone(), + funds: funds.clone(), + }; let res = self.call_execute( api, storage, From 05cf44454d4f7f9220fa1913a6488c8c751db8b8 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 15:43:41 +0100 Subject: [PATCH 140/631] clippy --- packages/multi-test/src/app.rs | 6 +++--- packages/multi-test/src/contracts.rs | 4 ++-- packages/multi-test/src/executor.rs | 2 +- packages/multi-test/src/wasm.rs | 5 +---- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 25c50d312..0f72cd698 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2598,7 +2598,7 @@ mod test { // execute should error let err = app - .execute_contract(Addr::unchecked("random"), contract_addr.clone(), &msg, &[]) + .execute_contract(Addr::unchecked("random"), contract_addr, &msg, &[]) .unwrap_err(); // we should be able to retrieve the original error by downcasting @@ -2638,7 +2638,7 @@ mod test { funds: vec![], }; let err = app - .execute_contract(Addr::unchecked("random"), caller_addr.clone(), &msg, &[]) + .execute_contract(Addr::unchecked("random"), caller_addr, &msg, &[]) .unwrap_err(); // we can downcast to get the original error @@ -2686,7 +2686,7 @@ mod test { funds: vec![], }; let err = app - .execute_contract(Addr::unchecked("random"), caller_addr1.clone(), &msg, &[]) + .execute_contract(Addr::unchecked("random"), caller_addr1, &msg, &[]) .unwrap_err(); // we can downcast to get the original error diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 1cb04509c..6c190a81c 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -339,8 +339,8 @@ where msg: Vec, ) -> AnyResult> { let msg: T1 = from_slice(&msg)?; - (self.execute_fn)(deps, env, info.clone(), msg.clone()) - .map_err(|err| anyhow::Error::from(err)) + (self.execute_fn)(deps, env, info, msg.clone()) + .map_err(anyhow::Error::from) .context(format!( "Contract returned an error on execute msg:\n{:?}", msg, diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index 0ab199413..53653ba02 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -111,7 +111,7 @@ where msg: binary_msg, funds: send_funds.to_vec(), }; - let mut res = self.execute(sender.clone(), wrapped_msg.into())?; + let mut res = self.execute(sender, wrapped_msg.into())?; res.data = res .data .and_then(|d| parse_execute_response_data(d.as_slice()).unwrap().data); diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 542c485d0..56279925b 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -301,10 +301,7 @@ where )?; // then call the contract - let info = MessageInfo { - sender: sender.clone(), - funds: funds.clone(), - }; + let info = MessageInfo { sender, funds }; let res = self.call_execute( api, storage, From 3eb5e2d013c6f8a2aee0cf4a18f36e10755236fb Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 15:50:06 +0100 Subject: [PATCH 141/631] multitest: test comments --- packages/multi-test/src/app.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 0f72cd698..8827c7c55 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2609,7 +2609,7 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 3 wrapped errors + // we're expecting exactly 3 nested error types // (the original error, execute msg context, WasmMsg context) assert_eq!(err.chain().count(), 3); } @@ -2649,7 +2649,7 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 4 wrapped errors + // we're expecting exactly 4 nested error types // (the original error, execute msg context, 2 WasmMsg contexts) assert_eq!(err.chain().count(), 4); } @@ -2689,6 +2689,9 @@ mod test { .execute_contract(Addr::unchecked("random"), caller_addr1, &msg, &[]) .unwrap_err(); + // uncomment to have the test fail and see how the error stringifies + // panic!("{:?}", err); + // we can downcast to get the original error let source: &StdError = err.downcast_ref().unwrap(); if let StdError::GenericErr { msg } = source { @@ -2697,7 +2700,7 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 5 wrapped errors + // we're expecting exactly 5 nested error types // (the original error, execute msg context, 3 WasmMsg contexts) assert_eq!(err.chain().count(), 5); } From 708e572e1e200bd6b60312747de7cf0c6790f49b Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 21:02:58 +0100 Subject: [PATCH 142/631] multitest: style --- packages/multi-test/src/executor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index c756653d4..b6eb341e1 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -107,7 +107,7 @@ where ) -> AnyResult { let binary_msg = to_binary(msg)?; let wrapped_msg = WasmMsg::Execute { - contract_addr: contract_addr.to_string(), + contract_addr: contract_addr.into_string(), msg: binary_msg, funds: send_funds.to_vec(), }; From ef50e4b96e505e3ee0ea9352352325b3707edadf Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 21:17:56 +0100 Subject: [PATCH 143/631] multitest: context for queries and instantiations --- packages/multi-test/src/app.rs | 25 +++++++++++++++++++++++++ packages/multi-test/src/contracts.rs | 26 ++++++++++++++++++-------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 34dec22e8..326d54587 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2584,6 +2584,31 @@ mod test { mod errors { use super::*; + #[test] + fn simple_instantiation() { + let owner = Addr::unchecked("owner"); + let mut app = App::default(); + + // set up contract + let code_id = app.store_code(error::contract(false)); + let msg = EmptyMsg {}; + let err = app + .instantiate_contract(code_id, owner, &msg, &[], "error", None) + .unwrap_err(); + + // we should be able to retrieve the original error by downcasting + let source: &StdError = err.downcast_ref().unwrap(); + if let StdError::GenericErr { msg } = source { + assert_eq!(msg, "Init failed"); + } else { + panic!("wrong StdError variant"); + } + + // we're expecting exactly 3 nested error types + // (the original error, initiate msg context, WasmMsg context) + assert_eq!(err.chain().count(), 3); + } + #[test] fn simple_call() { let owner = Addr::unchecked("owner"); diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 6c190a81c..e703b75a8 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -319,13 +319,13 @@ impl Contract for ContractWrapper where T1: DeserializeOwned + Debug + Clone, - T2: DeserializeOwned, - T3: DeserializeOwned, + T2: DeserializeOwned + Debug + Clone, + T3: DeserializeOwned + Debug + Clone, T4: DeserializeOwned, T6: DeserializeOwned, E1: Display + Debug + Send + Sync + Error + 'static, - E2: Display + Debug + Send + Sync + 'static, - E3: Display + Debug + Send + Sync + 'static, + E2: Display + Debug + Send + Sync + Error + 'static, + E3: Display + Debug + Send + Sync + Error + 'static, E4: Display + Debug + Send + Sync + 'static, E5: Display + Debug + Send + Sync + 'static, E6: Display + Debug + Send + Sync + 'static, @@ -354,13 +354,23 @@ where info: MessageInfo, msg: Vec, ) -> AnyResult> { - let msg = from_slice(&msg)?; - (self.instantiate_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) + let msg: T2 = from_slice(&msg)?; + (self.instantiate_fn)(deps, env, info, msg.clone()) + .map_err(anyhow::Error::from) + .context(format!( + "Contract returned an error on instantiate msg:\n{:?}", + msg, + )) } fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult { - let msg = from_slice(&msg)?; - (self.query_fn)(deps, env, msg).map_err(|err| anyhow!(err)) + let msg: T3 = from_slice(&msg)?; + (self.query_fn)(deps, env, msg.clone()) + .map_err(anyhow::Error::from) + .context(format!( + "Contract returned an error on query msg:\n{:?}", + msg, + )) } // this returns an error if the contract doesn't implement sudo From ede69a5714a0c0be6faf22867179fd577415d770 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 4 Jan 2022 21:33:44 +0100 Subject: [PATCH 144/631] cw1-whitelist: missing InstantiateMsg derives --- contracts/cw1-whitelist/src/msg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw1-whitelist/src/msg.rs b/contracts/cw1-whitelist/src/msg.rs index f0c4f04c1..bdfb6d2f5 100644 --- a/contracts/cw1-whitelist/src/msg.rs +++ b/contracts/cw1-whitelist/src/msg.rs @@ -4,7 +4,7 @@ use std::fmt; use cosmwasm_std::{CosmosMsg, Empty}; -#[derive(Serialize, Deserialize, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct InstantiateMsg { pub admins: Vec, pub mutable: bool, From 4bba3a5fb7965a670c0928dee25d3243cb2a15c0 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 10:12:08 +0100 Subject: [PATCH 145/631] Publish snapshot map changelog --- packages/storage-plus/src/snapshot/map.rs | 6 +++++- packages/storage-plus/src/snapshot/mod.rs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index ef1d572b4..e8365fa57 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -9,7 +9,7 @@ use crate::keys::PrimaryKey; use crate::map::Map; use crate::path::Path; use crate::prefix::{namespaced_prefix_range, Prefix, PrefixBound}; -use crate::snapshot::Snapshot; +use crate::snapshot::{ChangeSet, Snapshot}; use crate::{Bound, Prefixer, Strategy}; /// Map that maintains a snapshots of one or more checkpoints. @@ -44,6 +44,10 @@ impl<'a, K, T> SnapshotMap<'a, K, T> { snapshots: Snapshot::new(checkpoints, changelog, strategy), } } + + pub fn changelog(&self) -> &Map<'a, (K, u64), ChangeSet> { + &self.snapshots.changelog + } } impl<'a, K, T> SnapshotMap<'a, K, T> diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index c20fe2e8d..889f1fad6 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -172,7 +172,7 @@ pub enum Strategy { } #[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] -pub(crate) struct ChangeSet { +pub struct ChangeSet { pub old: Option, } From 72a838d75eaec1738e66b43d4c72ed1b670d71e6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 12:18:34 +0100 Subject: [PATCH 146/631] Add changelog iterator tests --- packages/storage-plus/src/snapshot/map.rs | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs index e8365fa57..64a042da4 100644 --- a/packages/storage-plus/src/snapshot/map.rs +++ b/packages/storage-plus/src/snapshot/map.rs @@ -462,6 +462,70 @@ mod tests { ); } + #[test] + #[cfg(feature = "iterator")] + fn changelog_range_works() { + use cosmwasm_std::Order; + + let mut store = MockStorage::new(); + + // simple data for testing + EVERY.save(&mut store, "A", &5, 1).unwrap(); + EVERY.save(&mut store, "B", &7, 2).unwrap(); + EVERY + .update(&mut store, "A", 3, |_| -> StdResult { Ok(8) }) + .unwrap(); + EVERY.remove(&mut store, "B", 4).unwrap(); + + // let's try to iterate over the changelog + let all: StdResult> = EVERY + .changelog() + .range(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(4, all.len()); + assert_eq!( + all, + vec![ + (("A".into(), 1), ChangeSet { old: None }), + (("A".into(), 3), ChangeSet { old: Some(5) }), + (("B".into(), 2), ChangeSet { old: None }), + (("B".into(), 4), ChangeSet { old: Some(7) }) + ] + ); + + // let's try to iterate over a changelog key/prefix + let all: StdResult> = EVERY + .changelog() + .prefix("B") + .range(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(2, all.len()); + assert_eq!( + all, + vec![ + (2, ChangeSet { old: None }), + (4, ChangeSet { old: Some(7) }) + ] + ); + + // let's try to iterate over a changelog prefixed range + let all: StdResult> = EVERY + .changelog() + .prefix("A") + .range( + &store, + Some(Bound::inclusive_int(3u64)), + None, + Order::Ascending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(3, ChangeSet { old: Some(5) }),]); + } + #[test] #[cfg(feature = "iterator")] fn range_simple_string_key() { From 1f7599cbf8ccb9e60456a268c2855be56f5b6d7e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 15:55:30 +0100 Subject: [PATCH 147/631] Move namespace() method to right trait (un)bounded scope --- packages/storage-plus/src/map.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 94d78bdcd..45a89c294 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -31,6 +31,10 @@ impl<'a, K, T> Map<'a, K, T> { key_type: PhantomData, } } + + pub fn namespace(&self) -> &'a [u8] { + self.namespace + } } impl<'a, K, T> Map<'a, K, T> @@ -38,10 +42,6 @@ where T: Serialize + DeserializeOwned, K: PrimaryKey<'a>, { - pub fn namespace(&self) -> &'a [u8] { - self.namespace - } - pub fn key(&self, k: K) -> Path { Path::new( self.namespace, From c5982901ce14f23a00f3a3fa8cad230f928606f4 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 16:00:24 +0100 Subject: [PATCH 148/631] Publish snapshot item changelog --- packages/storage-plus/src/snapshot/item.rs | 58 +++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs index 58dcf9707..6dfa12550 100644 --- a/packages/storage-plus/src/snapshot/item.rs +++ b/packages/storage-plus/src/snapshot/item.rs @@ -3,8 +3,9 @@ use serde::Serialize; use cosmwasm_std::{StdError, StdResult, Storage}; -use crate::snapshot::Snapshot; -use crate::{Item, Strategy}; +use crate::snapshot::{ChangeSet, Snapshot}; +use crate::{Item, Map, Strategy}; +use std::str::from_utf8_unchecked; /// Item that maintains a snapshot of one or more checkpoints. /// We can query historical data as well as current state. @@ -45,6 +46,11 @@ impl<'a, T> SnapshotItem<'a, T> { pub fn remove_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { self.snapshots.remove_checkpoint(store, height) } + + pub fn changelog(&self) -> Map> { + // Build and return a compatible Map with the proper key type + Map::new(unsafe { from_utf8_unchecked(self.snapshots.changelog.namespace()) }) + } } impl<'a, T> SnapshotItem<'a, T> @@ -272,4 +278,52 @@ mod tests { assert_eq!(None, EVERY.may_load_at_height(&storage, 5).unwrap()); assert_eq!(Some(2), EVERY.may_load_at_height(&storage, 6).unwrap()); } + + #[test] + #[cfg(feature = "iterator")] + fn changelog_range_works() { + use crate::Bound; + use cosmwasm_std::Order; + + let mut store = MockStorage::new(); + + // simple data for testing + EVERY.save(&mut store, &5, 1u64).unwrap(); + EVERY.save(&mut store, &7, 2u64).unwrap(); + EVERY + .update(&mut store, 3u64, |_| -> StdResult { Ok(8) }) + .unwrap(); + EVERY.remove(&mut store, 4u64).unwrap(); + + // let's try to iterate over the changelog + let all: StdResult> = EVERY + .changelog() + .range(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(4, all.len()); + assert_eq!( + all, + vec![ + (1, ChangeSet { old: None }), + (2, ChangeSet { old: Some(5) }), + (3, ChangeSet { old: Some(7) }), + (4, ChangeSet { old: Some(8) }) + ] + ); + + // let's try to iterate over a changelog range + let all: StdResult> = EVERY + .changelog() + .range( + &store, + Some(Bound::exclusive_int(3u64)), + None, + Order::Ascending, + ) + .collect(); + let all = all.unwrap(); + assert_eq!(1, all.len()); + assert_eq!(all, vec![(4, ChangeSet { old: Some(8) }),]); + } } From 164325328af104cda334f14c010616fe4564f390 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 16:05:35 +0100 Subject: [PATCH 149/631] Publish indexed snapshot map changelog as well --- packages/storage-plus/src/indexed_snapshot.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 7b2eb7b82..5ed1d3dda 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -9,8 +9,8 @@ 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::snapshot::SnapshotMap; -use crate::{IndexList, Path, Strategy}; +use crate::snapshot::{ChangeSet, SnapshotMap}; +use crate::{IndexList, Map, Path, Strategy}; /// `IndexedSnapshotMap` works like a `SnapshotMap` but has a secondary index pub struct IndexedSnapshotMap<'a, K, T, I> { @@ -56,6 +56,10 @@ impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> { idx: indexes, } } + + pub fn changelog(&self) -> &Map<'a, (K, u64), ChangeSet> { + &self.primary.changelog() + } } impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> From 9c8954be62395b636ae8cf8e4c1bfdbf4f912ced Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 4 Jan 2022 16:21:24 +0100 Subject: [PATCH 150/631] Add indexed snapshot map changelog tests --- packages/storage-plus/src/indexed_snapshot.rs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 5ed1d3dda..8476572bd 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -611,6 +611,65 @@ mod test { assert_eq!(marias[1].1, data1); } + #[test] + fn changelog_range_works() { + let mut store = MockStorage::new(); + let map = build_snapshot_map(); + let mut height = 1; + + // simple data for testing + // EVERY.remove(&mut store, "B", 4).unwrap(); + let data1 = Data { + name: "Maria".to_string(), + last_name: "".to_string(), + age: 42, + }; + let pk_a = "A"; + map.save(&mut store, pk_a, &data1, height).unwrap(); + height += 1; + + let data2 = Data { + name: "Juan".to_string(), + last_name: "Perez".to_string(), + age: 13, + }; + let pk_b = "B"; + map.save(&mut store, pk_b, &data2, height).unwrap(); + height += 1; + + let data3 = Data { + name: "Maria".to_string(), + last_name: "Williams".to_string(), + age: 24, + }; + map.update(&mut store, pk_a, height, |_| -> StdResult { + Ok(data3) + }) + .unwrap(); + + height += 1; + map.remove(&mut store, pk_b, height).unwrap(); + + let changes: Vec<_> = map + .changelog() + .range(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + let count = changes.len(); + assert_eq!(4, count); + + // sorted by ascending key, height + assert_eq!( + changes, + vec![ + (("A".into(), 1), ChangeSet { old: None }), + (("A".into(), 3), ChangeSet { old: Some(data1) }), + (("B".into(), 2), ChangeSet { old: None }), + (("B".into(), 4), ChangeSet { old: Some(data2) }) + ] + ); + } + #[test] fn range_raw_composite_key_by_multi_index() { let mut store = MockStorage::new(); From a797917dc01844f4c85c62f14ac83edc87e8c978 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 5 Jan 2022 08:33:15 +0100 Subject: [PATCH 151/631] Store changelog namespace ref to avoid re-conversion --- packages/storage-plus/src/snapshot/item.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs index 6dfa12550..3cf9bfa0a 100644 --- a/packages/storage-plus/src/snapshot/item.rs +++ b/packages/storage-plus/src/snapshot/item.rs @@ -5,13 +5,13 @@ use cosmwasm_std::{StdError, StdResult, Storage}; use crate::snapshot::{ChangeSet, Snapshot}; use crate::{Item, Map, Strategy}; -use std::str::from_utf8_unchecked; /// Item that maintains a snapshot of one or more checkpoints. /// We can query historical data as well as current state. /// What data is snapshotted depends on the Strategy. pub struct SnapshotItem<'a, T> { primary: Item<'a, T>, + changelog_namespace: &'a str, snapshots: Snapshot<'a, (), T>, } @@ -35,6 +35,7 @@ impl<'a, T> SnapshotItem<'a, T> { ) -> Self { SnapshotItem { primary: Item::new(storage_key), + changelog_namespace: changelog, snapshots: Snapshot::new(checkpoints, changelog, strategy), } } @@ -49,7 +50,7 @@ impl<'a, T> SnapshotItem<'a, T> { pub fn changelog(&self) -> Map> { // Build and return a compatible Map with the proper key type - Map::new(unsafe { from_utf8_unchecked(self.snapshots.changelog.namespace()) }) + Map::new(self.changelog_namespace) } } From 19d7bd9f84aaca7e736aa3eaf1f6d8ac9cbf50ec Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 5 Jan 2022 11:02:37 +0100 Subject: [PATCH 152/631] New SECURITY.md refering to wasmd --- SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..1b10ff8e5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +cw-plus is still pre v1.0. A best effort has been made that the contracts here are secure, and we have moved the more +experimental contracts into community repositories like [cw-nfts](https://github.com/CosmWasm/cw-nfts) and +[cw-tokens](https://github.com/CosmWasm/cw-tokens). That said, we have not done an audit on them (formal or informal) +and you can use them at your own risk. We highly suggest doing your own audit on any contract you plan to deploy +with significant token value, and please inform us if it detects any issues so we can upstream them. + +Until v1.0 APIs are subject to change. The contracts APIs are pretty much stable, most work is currently +in `storage-plus` and `multi-test`. + +## Reporting a Vulnerability + +We have a [unified security policy](https://github.com/CosmWasm/wasmd/blob/master/SECURITY.md) +for all CosmWasm-related repositories maintained by Confio. +You can [read it here](https://github.com/CosmWasm/wasmd/blob/master/SECURITY.md) From f9f87dbefa1e9a5ff236329c642e74487fb64c94 Mon Sep 17 00:00:00 2001 From: Josef Richter Date: Mon, 17 Jan 2022 15:02:01 +0100 Subject: [PATCH 153/631] Create README.md fix a typo "sue" -> "use" (or maybe it was supposed to be "see"?) --- packages/storage-plus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 8fe31abff..214228bd5 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -409,7 +409,7 @@ fn demo() -> StdResult<()> { ## IndexedMap -Let's sue one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. +Let's use one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. ### Definition From 2c0f9851f123004139d5fb1f1a843a1f4c77b525 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 15:12:45 +0100 Subject: [PATCH 154/631] Add allowlist and govcontract to init --- contracts/cw20-ics20/src/contract.rs | 26 +++++++++++++++++++++--- contracts/cw20-ics20/src/msg.rs | 12 +++++++++++ contracts/cw20-ics20/src/state.rs | 17 ++++++++++++---- contracts/cw20-ics20/src/test_helpers.rs | 2 ++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index fc4ffb7e6..ecc35fb2b 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -12,10 +12,10 @@ use crate::amount::Amount; use crate::error::ContractError; use crate::ibc::Ics20Packet; use crate::msg::{ - ChannelResponse, ExecuteMsg, InitMsg, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, - TransferMsg, + AllowMsg, ChannelResponse, ExecuteMsg, InitMsg, ListChannelsResponse, MigrateMsg, PortResponse, + QueryMsg, TransferMsg, }; -use crate::state::{Config, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; +use crate::state::{AllowInfo, Config, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; use cw_utils::{nonpayable, one_coin}; // version info for migration info @@ -32,8 +32,18 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { default_timeout: msg.default_timeout, + gov_contract: deps.api.addr_validate(&msg.gov_contract)?, }; CONFIG.save(deps.storage, &cfg)?; + + // add all allows + for allowed in msg.allowlist { + let contract = deps.api.addr_validate(&allowed.contract)?; + let info = AllowInfo { + gas_limit: allowed.gas_limit, + }; + ALLOW_LIST.save(deps.storage, &contract, &info)?; + } Ok(Response::default()) } @@ -50,6 +60,7 @@ pub fn execute( let coin = one_coin(&info)?; execute_transfer(deps, env, msg, Amount::Native(coin), info.sender) } + ExecuteMsg::Allow(allow) => execute_allow(deps, env, info, allow), } } @@ -124,6 +135,15 @@ pub fn execute_transfer( Ok(res) } +pub fn execute_allow( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _allow: AllowMsg, +) -> Result { + unimplemented!() +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { let version = get_contract_version(deps.storage)?; diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index afa0c6259..39fa6fdd8 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -10,6 +10,16 @@ use crate::state::ChannelInfo; pub struct InitMsg { /// Default timeout for ics20 packets, specified in seconds pub default_timeout: u64, + /// who can allow more contracts + pub gov_contract: String, + /// initial allowlist - all cw20 tokens we will send must be previously allowed by governance + pub allowlist: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct AllowMsg { + pub contract: String, + pub gas_limit: Option, } #[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] @@ -22,6 +32,8 @@ pub enum ExecuteMsg { Receive(Cw20ReceiveMsg), /// This allows us to transfer *exactly one* native token Transfer(TransferMsg), + /// This must be called by gov_contract, will allow a new cw20 token to be sent + Allow(AllowMsg), } /// This is the message we accept via Receive diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 1b1af2b52..b87307a65 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -1,26 +1,30 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{IbcEndpoint, Uint128}; +use cosmwasm_std::{Addr, IbcEndpoint, Uint128}; use cw_storage_plus::{Item, Map}; pub const CONFIG: Item = Item::new("ics20_config"); -// static info on one channel that doesn't change +/// static info on one channel that doesn't change pub const CHANNEL_INFO: Map<&str, ChannelInfo> = Map::new("channel_info"); -// indexed by (channel_id, denom) maintaining the balance of the channel in that currency +/// indexed by (channel_id, denom) maintaining the balance of the channel in that currency pub const CHANNEL_STATE: Map<(&str, &str), ChannelState> = Map::new("channel_state"); +/// Every cw20 contract we allow to be sent is stored here, possibly with a gas_limit +pub const ALLOW_LIST: Map<&Addr, AllowInfo> = Map::new("allow_list"); + #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] pub struct ChannelState { pub outstanding: Uint128, pub total_sent: Uint128, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { pub default_timeout: u64, + pub gov_contract: Addr, } #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] @@ -32,3 +36,8 @@ pub struct ChannelInfo { /// the connection this exists on (you can use to query client/consensus info) pub connection_id: String, } + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct AllowInfo { + pub gas_limit: Option, +} diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 501d6af0b..1dad4a7ca 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -60,6 +60,8 @@ pub fn setup(channels: &[&str]) -> OwnedDeps // instantiate an empty contract let instantiate_msg = InitMsg { default_timeout: DEFAULT_TIMEOUT, + gov_contract: "gov".to_string(), + allowlist: vec![], }; let info = mock_info(&String::from("anyone"), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); From ba811c0b42028591e926389665624fc7c6f60889 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 15:24:54 +0100 Subject: [PATCH 155/631] Implement execute_allow --- contracts/cw20-ics20/src/contract.rs | 45 ++++++++++++++++++++++++---- contracts/cw20-ics20/src/error.rs | 6 ++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index ecc35fb2b..2ffdfcd2b 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, Order, - PortIdResponse, Response, StdResult, + ensure_eq, from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, + MessageInfo, Order, PortIdResponse, Response, StdResult, }; use cw2::{get_contract_version, set_contract_version}; @@ -135,13 +135,46 @@ pub fn execute_transfer( Ok(res) } +/// The gov contract can allow new contracts, or increase the gas limit on existing contracts. +/// It cannot block or reduce the limit to avoid forcible sticking tokens in the channel. pub fn execute_allow( - _deps: DepsMut, + deps: DepsMut, _env: Env, - _info: MessageInfo, - _allow: AllowMsg, + info: MessageInfo, + allow: AllowMsg, ) -> Result { - unimplemented!() + let cfg = CONFIG.load(deps.storage)?; + ensure_eq!(info.sender, cfg.gov_contract, ContractError::Unauthorized); + + let contract = deps.api.addr_validate(&allow.contract)?; + let set = AllowInfo { + gas_limit: allow.gas_limit, + }; + ALLOW_LIST.update(deps.storage, &contract, |old| { + if let Some(old) = old { + // we must ensure it increases the limit + match (old.gas_limit, set.gas_limit) { + (None, Some(_)) => return Err(ContractError::CannotLowerGas), + (Some(old), Some(new)) if new < old => return Err(ContractError::CannotLowerGas), + _ => {} + }; + } + Ok(AllowInfo { + gas_limit: allow.gas_limit, + }) + })?; + + let gas = if let Some(gas) = allow.gas_limit { + gas.to_string() + } else { + "None".to_string() + }; + + let res = Response::new() + .add_attribute("action", "allow") + .add_attribute("contract", allow.contract) + .add_attribute("gas_limit", gas); + Ok(res) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/cw20-ics20/src/error.rs b/contracts/cw20-ics20/src/error.rs index c20a0b4d5..78b11ac75 100644 --- a/contracts/cw20-ics20/src/error.rs +++ b/contracts/cw20-ics20/src/error.rs @@ -49,6 +49,12 @@ pub enum ContractError { #[error("Got a submessage reply with unknown id: {id}")] UnknownReplyId { id: u64 }, + + #[error("You cannot lower the gas limit for a contract on the allow list")] + CannotLowerGas, + + #[error("Only the governance contract can do this")] + Unauthorized, } impl From for ContractError { From 523770b1dfc50b52382c079907cb57e57582dfa6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 17:45:24 +0100 Subject: [PATCH 156/631] Add queries for allowances --- contracts/cw20-ics20/src/contract.rs | 63 +++++++++++++++++++++++++++- contracts/cw20-ics20/src/msg.rs | 33 +++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 2ffdfcd2b..c0c2f3c07 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -7,13 +7,14 @@ use cosmwasm_std::{ use cw2::{get_contract_version, set_contract_version}; use cw20::{Cw20Coin, Cw20ReceiveMsg}; +use cw_storage_plus::Bound; use crate::amount::Amount; use crate::error::ContractError; use crate::ibc::Ics20Packet; use crate::msg::{ - AllowMsg, ChannelResponse, ExecuteMsg, InitMsg, ListChannelsResponse, MigrateMsg, PortResponse, - QueryMsg, TransferMsg, + AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, + ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, }; use crate::state::{AllowInfo, Config, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; use cw_utils::{nonpayable, one_coin}; @@ -194,6 +195,11 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Port {} => to_binary(&query_port(deps)?), QueryMsg::ListChannels {} => to_binary(&query_list(deps)?), QueryMsg::Channel { id } => to_binary(&query_channel(deps, id)?), + QueryMsg::Config {} => to_binary(&query_config(deps)?), + QueryMsg::Allowed { contract } => to_binary(&query_allowed(deps, contract)?), + QueryMsg::ListAllowed { start_after, limit } => { + to_binary(&list_allowed(deps, start_after, limit)?) + } } } @@ -236,6 +242,59 @@ pub fn query_channel(deps: Deps, id: String) -> StdResult { }) } +fn query_config(deps: Deps) -> StdResult { + let cfg = CONFIG.load(deps.storage)?; + let res = ConfigResponse { + default_timeout: cfg.default_timeout, + gov_contract: cfg.gov_contract.into(), + }; + Ok(res) +} + +fn query_allowed(deps: Deps, contract: String) -> StdResult { + let addr = deps.api.addr_validate(&contract)?; + let info = ALLOW_LIST.may_load(deps.storage, &addr)?; + let res = match info { + None => AllowedResponse { + is_allowed: false, + gas_limit: None, + }, + Some(a) => AllowedResponse { + is_allowed: true, + gas_limit: a.gas_limit, + }, + }; + Ok(res) +} + +// settings for pagination +const MAX_LIMIT: u32 = 30; +const DEFAULT_LIMIT: u32 = 10; + +fn list_allowed( + deps: Deps, + start_after: Option, + 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 allow = ALLOW_LIST + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { + item.map(|(addr, allow)| AllowedInfo { + contract: addr.into(), + gas_limit: allow.gas_limit, + }) + }) + .collect::>()?; + Ok(ListAllowedResponse { allow }) +} + #[cfg(test)] mod test { use super::*; diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index 39fa6fdd8..ddaade744 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -49,6 +49,7 @@ pub struct TransferMsg { pub timeout: Option, } +// TODO: query config, query allow list #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { @@ -59,6 +60,15 @@ pub enum QueryMsg { /// Returns the details of the name channel, error if not created. /// Return type: ChannelResponse. Channel { id: String }, + /// Show the Config. Returns ConfigResponse + Config {}, + /// Query if a given cw20 contract is allowed. Returns AllowedResponse + Allowed { contract: String }, + /// List all allowed cw20 contracts. Returns ListAllowedResponse + ListAllowed { + start_after: Option, + limit: Option, + }, } #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] @@ -81,3 +91,26 @@ pub struct ChannelResponse { pub struct PortResponse { pub port_id: String, } + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct ConfigResponse { + pub default_timeout: u64, + pub gov_contract: String, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct AllowedResponse { + pub is_allowed: bool, + pub gas_limit: Option, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct ListAllowedResponse { + pub allow: Vec, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct AllowedInfo { + pub contract: String, + pub gas_limit: Option, +} From 48f29d3e398dc0277a1f1fb0ea0c9b2a2a8eea7f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 17:54:51 +0100 Subject: [PATCH 157/631] Add whitelist check to transfer --- contracts/cw20-ics20/src/contract.rs | 25 ++++++++++++++++++------- contracts/cw20-ics20/src/error.rs | 3 +++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index c0c2f3c07..c5cd7b7fd 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ ensure_eq, from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, - MessageInfo, Order, PortIdResponse, Response, StdResult, + MessageInfo, Order, PortIdResponse, Response, StdResult, SubMsg, }; use cw2::{get_contract_version, set_contract_version}; @@ -93,11 +93,21 @@ pub fn execute_transfer( return Err(ContractError::NoFunds {}); } // ensure the requested channel is registered - // FIXME: add a .has method to map to make this faster - if CHANNEL_INFO.may_load(deps.storage, &msg.channel)?.is_none() { + if CHANNEL_INFO.has(deps.storage, &msg.channel) { return Err(ContractError::NoSuchChannel { id: msg.channel }); } + // if cw20 token, ensure it is whitelisted, and use the registered gas limit + let gas_limit = if let Amount::Cw20(coin) = &amount { + let addr = deps.api.addr_validate(&coin.address)?; + let allow = ALLOW_LIST + .may_load(deps.storage, &addr)? + .ok_or(ContractError::NotOnAllowList)?; + allow.gas_limit + } else { + None + }; + // delta from user is in seconds let timeout_delta = match msg.timeout { Some(t) => t, @@ -115,19 +125,20 @@ pub fn execute_transfer( ); packet.validate()?; - // prepare message - let msg = IbcMsg::SendPacket { + // prepare message and set proper gas limit + let mut msg = SubMsg::new(IbcMsg::SendPacket { channel_id: msg.channel, data: to_binary(&packet)?, timeout: timeout.into(), - }; + }); + msg.gas_limit = gas_limit; // Note: we update local state when we get ack - do not count this transfer towards anything until acked // similar event messages like ibctransfer module // send response let res = Response::new() - .add_message(msg) + .add_submessage(msg) .add_attribute("action", "transfer") .add_attribute("sender", &packet.sender) .add_attribute("receiver", &packet.receiver) diff --git a/contracts/cw20-ics20/src/error.rs b/contracts/cw20-ics20/src/error.rs index 78b11ac75..cdd3b0574 100644 --- a/contracts/cw20-ics20/src/error.rs +++ b/contracts/cw20-ics20/src/error.rs @@ -55,6 +55,9 @@ pub enum ContractError { #[error("Only the governance contract can do this")] Unauthorized, + + #[error("You can only send cw20 tokens that have been explicitly allowed by governance")] + NotOnAllowList, } impl From for ContractError { From 0aff8cda83d6f86c3f621a7813544808edc0934c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 18:03:10 +0100 Subject: [PATCH 158/631] Enforce cw20 whitelist on transfers --- contracts/cw20-ics20/src/contract.rs | 36 ++++++++++++++++++++---- contracts/cw20-ics20/src/ibc.rs | 8 ++++-- contracts/cw20-ics20/src/test_helpers.rs | 17 +++++++++-- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index c5cd7b7fd..d28d3a6de 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -93,7 +93,7 @@ pub fn execute_transfer( return Err(ContractError::NoFunds {}); } // ensure the requested channel is registered - if CHANNEL_INFO.has(deps.storage, &msg.channel) { + if !CHANNEL_INFO.has(deps.storage, &msg.channel) { return Err(ContractError::NoSuchChannel { id: msg.channel }); } @@ -318,7 +318,7 @@ mod test { #[test] fn setup_and_query() { - let deps = setup(&["channel-3", "channel-7"]); + let deps = setup(&["channel-3", "channel-7"], &[]); let raw_list = query(deps.as_ref(), mock_env(), QueryMsg::ListChannels {}).unwrap(); let list_res: ListChannelsResponse = from_binary(&raw_list).unwrap(); @@ -353,7 +353,7 @@ mod test { #[test] fn proper_checks_on_execute_native() { let send_channel = "channel-5"; - let mut deps = setup(&[send_channel, "channel-10"]); + let mut deps = setup(&[send_channel, "channel-10"], &[]); let mut transfer = TransferMsg { channel: send_channel.to_string(), @@ -365,6 +365,7 @@ mod test { let msg = ExecuteMsg::Transfer(transfer.clone()); let info = mock_info("foobar", &coins(1234567, "ucosm")); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(res.messages[0].gas_limit, None); assert_eq!(1, res.messages.len()); if let CosmosMsg::Ibc(IbcMsg::SendPacket { channel_id, @@ -412,9 +413,10 @@ mod test { #[test] fn proper_checks_on_execute_cw20() { let send_channel = "channel-15"; - let mut deps = setup(&["channel-3", send_channel]); - let cw20_addr = "my-token"; + let gas_limit = 123456; + let mut deps = setup(&["channel-3", send_channel], &[(cw20_addr, gas_limit)]); + let transfer = TransferMsg { channel: send_channel.to_string(), remote_address: "foreign-address".to_string(), @@ -430,6 +432,7 @@ mod test { let info = mock_info(cw20_addr, &[]); let res = execute(deps.as_mut(), mock_env(), info, msg.clone()).unwrap(); assert_eq!(1, res.messages.len()); + assert_eq!(res.messages[0].gas_limit, Some(gas_limit)); if let CosmosMsg::Ibc(IbcMsg::SendPacket { channel_id, data, @@ -453,4 +456,27 @@ mod test { let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Payment(PaymentError::NonPayable {})); } + + #[test] + fn execute_cw20_fails_if_not_whitelisted() { + let send_channel = "channel-15"; + let mut deps = setup(&["channel-3", send_channel], &[]); + + let cw20_addr = "my-token"; + let transfer = TransferMsg { + channel: send_channel.to_string(), + remote_address: "foreign-address".to_string(), + timeout: Some(7777), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "my-account".into(), + amount: Uint128::new(888777666), + msg: to_binary(&transfer).unwrap(), + }); + + // works with proper funds + let info = mock_info(cw20_addr, &[]); + let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); + assert_eq!(err, ContractError::NotOnAllowList); + } } diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 3fe4711af..d851973b6 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -465,10 +465,12 @@ mod test { #[test] fn send_receive_cw20() { let send_channel = "channel-9"; - let mut deps = setup(&["channel-1", "channel-7", send_channel]); - let cw20_addr = "token-addr"; let cw20_denom = "cw20:token-addr"; + let mut deps = setup( + &["channel-1", "channel-7", send_channel], + &[(cw20_addr, 1234567)], + ); // prepare some mock packets let sent_packet = mock_sent_packet(send_channel, 987654321, cw20_denom, "local-sender"); @@ -521,7 +523,7 @@ mod test { #[test] fn send_receive_native() { let send_channel = "channel-9"; - let mut deps = setup(&["channel-1", "channel-7", send_channel]); + let mut deps = setup(&["channel-1", "channel-7", send_channel], &[]); let denom = "uatom"; diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 1dad4a7ca..27106d66f 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -11,7 +11,7 @@ use cosmwasm_std::{ DepsMut, IbcChannel, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, OwnedDeps, }; -use crate::msg::InitMsg; +use crate::msg::{AllowMsg, InitMsg}; pub const DEFAULT_TIMEOUT: u64 = 3600; // 1 hour, pub const CONTRACT_PORT: &str = "ibc:wasm1234567890abcdef"; @@ -54,14 +54,25 @@ pub fn add_channel(mut deps: DepsMut, channel_id: &str) { ibc_channel_connect(deps.branch(), mock_env(), connect_msg).unwrap(); } -pub fn setup(channels: &[&str]) -> OwnedDeps { +pub fn setup( + channels: &[&str], + allow: &[(&str, u64)], +) -> OwnedDeps { let mut deps = mock_dependencies(); + let allowlist = allow + .iter() + .map(|(contract, gas)| AllowMsg { + contract: contract.to_string(), + gas_limit: Some(*gas), + }) + .collect(); + // instantiate an empty contract let instantiate_msg = InitMsg { default_timeout: DEFAULT_TIMEOUT, gov_contract: "gov".to_string(), - allowlist: vec![], + allowlist, }; let info = mock_info(&String::from("anyone"), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); From 0cc42b95e51be59938758e5749bf1fc2455fad96 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 18:07:39 +0100 Subject: [PATCH 159/631] Remove mistaken gas limit on ibc packet send --- contracts/cw20-ics20/src/contract.rs | 23 +++++++++-------------- contracts/cw20-ics20/src/ibc.rs | 12 ++++++++++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index d28d3a6de..22428f878 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ ensure_eq, from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, - MessageInfo, Order, PortIdResponse, Response, StdResult, SubMsg, + MessageInfo, Order, PortIdResponse, Response, StdResult, }; use cw2::{get_contract_version, set_contract_version}; @@ -97,15 +97,12 @@ pub fn execute_transfer( return Err(ContractError::NoSuchChannel { id: msg.channel }); } - // if cw20 token, ensure it is whitelisted, and use the registered gas limit - let gas_limit = if let Amount::Cw20(coin) = &amount { + // if cw20 token, ensure it is whitelisted + if let Amount::Cw20(coin) = &amount { let addr = deps.api.addr_validate(&coin.address)?; - let allow = ALLOW_LIST + ALLOW_LIST .may_load(deps.storage, &addr)? .ok_or(ContractError::NotOnAllowList)?; - allow.gas_limit - } else { - None }; // delta from user is in seconds @@ -126,19 +123,18 @@ pub fn execute_transfer( packet.validate()?; // prepare message and set proper gas limit - let mut msg = SubMsg::new(IbcMsg::SendPacket { + let msg = IbcMsg::SendPacket { channel_id: msg.channel, data: to_binary(&packet)?, timeout: timeout.into(), - }); - msg.gas_limit = gas_limit; + }; // Note: we update local state when we get ack - do not count this transfer towards anything until acked // similar event messages like ibctransfer module // send response let res = Response::new() - .add_submessage(msg) + .add_message(msg) .add_attribute("action", "transfer") .add_attribute("sender", &packet.sender) .add_attribute("receiver", &packet.receiver) @@ -414,8 +410,7 @@ mod test { fn proper_checks_on_execute_cw20() { let send_channel = "channel-15"; let cw20_addr = "my-token"; - let gas_limit = 123456; - let mut deps = setup(&["channel-3", send_channel], &[(cw20_addr, gas_limit)]); + let mut deps = setup(&["channel-3", send_channel], &[(cw20_addr, 123456)]); let transfer = TransferMsg { channel: send_channel.to_string(), @@ -432,7 +427,7 @@ mod test { let info = mock_info(cw20_addr, &[]); let res = execute(deps.as_mut(), mock_env(), info, msg.clone()).unwrap(); assert_eq!(1, res.messages.len()); - assert_eq!(res.messages[0].gas_limit, Some(gas_limit)); + assert_eq!(res.messages[0].gas_limit, None); if let CosmosMsg::Ibc(IbcMsg::SendPacket { channel_id, data, diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index d851973b6..26aad11bf 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -181,6 +181,18 @@ pub fn ibc_packet_receive( attr("success", "true"), ]; let to_send = Amount::from_parts(denom.into(), msg.amount); + + // TODO: add check.. + // if cw20 token, ensure it is whitelisted, and use the registered gas limit + // let gas_limit = if let Amount::Cw20(coin) = &amount { + // let addr = deps.api.addr_validate(&coin.address)?; + // let allow = ALLOW_LIST + // .may_load(deps.storage, &addr)? + // .ok_or(ContractError::NotOnAllowList)?; + // allow.gas_limit + // } else { + // None + // }; let msg = send_amount(to_send, msg.receiver); IbcReceiveResponse::new() .set_ack(ack_success()) From 3b5954e9358c565d7bd4fc2c42c34d2bd2f75df2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 23:24:58 +0100 Subject: [PATCH 160/631] Clean up receive handler, limit gas on releasing cw20 tokens --- contracts/cw20-ics20/src/ibc.rs | 122 ++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 26aad11bf..6435dc589 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{ - attr, entry_point, from_binary, to_binary, BankMsg, Binary, ContractResult, DepsMut, Env, + attr, entry_point, from_binary, to_binary, BankMsg, Binary, ContractResult, Deps, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, StdResult, SubMsg, Uint128, WasmMsg, @@ -10,7 +10,7 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; -use crate::state::{ChannelInfo, CHANNEL_INFO, CHANNEL_STATE}; +use crate::state::{ChannelInfo, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE}; use cw20::Cw20ExecuteMsg; pub const ICS20_VERSION: &str = "ics20-1"; @@ -164,52 +164,15 @@ pub fn ibc_packet_receive( ) -> Result { let packet = msg.packet; - let res = match do_ibc_packet_receive(deps, &packet) { - Ok(msg) => { - // build attributes first so we don't have to clone msg below - // similar event messages like ibctransfer module - - // This cannot fail as we parse it in do_ibc_packet_receive. Best to pass the data somehow? - let denom = parse_voucher_denom(&msg.denom, &packet.src).unwrap(); - - let attributes = vec![ - attr("action", "receive"), - attr("sender", &msg.sender), - attr("receiver", &msg.receiver), - attr("denom", denom), - attr("amount", msg.amount), - attr("success", "true"), - ]; - let to_send = Amount::from_parts(denom.into(), msg.amount); - - // TODO: add check.. - // if cw20 token, ensure it is whitelisted, and use the registered gas limit - // let gas_limit = if let Amount::Cw20(coin) = &amount { - // let addr = deps.api.addr_validate(&coin.address)?; - // let allow = ALLOW_LIST - // .may_load(deps.storage, &addr)? - // .ok_or(ContractError::NotOnAllowList)?; - // allow.gas_limit - // } else { - // None - // }; - let msg = send_amount(to_send, msg.receiver); - IbcReceiveResponse::new() - .set_ack(ack_success()) - .add_submessage(msg) - .add_attributes(attributes) - } - Err(err) => IbcReceiveResponse::new() + do_ibc_packet_receive(deps, &packet).or_else(|err| { + Ok(IbcReceiveResponse::new() .set_ack(ack_fail(err.to_string())) .add_attributes(vec![ attr("action", "receive"), attr("success", "false"), attr("error", err.to_string()), - ]), - }; - - // if we have funds, now send the tokens to the requested recipient - Ok(res) + ])) + }) } // Returns local denom if the denom is an encoded voucher from the expected endpoint @@ -238,7 +201,10 @@ fn parse_voucher_denom<'a>( } // this does the work of ibc_packet_receive, we wrap it to turn errors into acknowledgements -fn do_ibc_packet_receive(deps: DepsMut, packet: &IbcPacket) -> Result { +fn do_ibc_packet_receive( + deps: DepsMut, + packet: &IbcPacket, +) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; let channel = packet.dest.channel_id.clone(); @@ -246,7 +212,6 @@ fn do_ibc_packet_receive(deps: DepsMut, packet: &IbcPacket) -> Result Result Result, ContractError> { + match amount { + Amount::Cw20(coin) => { + // if cw20 token, use the registered gas limit, or error if not whitelisted + let addr = deps.api.addr_validate(&coin.address)?; + Ok(ALLOW_LIST + .may_load(deps.storage, &addr)? + .ok_or(ContractError::NotOnAllowList)? + .gas_limit) + } + _ => Ok(None), + } } #[cfg_attr(not(feature = "library"), entry_point)] @@ -318,7 +319,7 @@ fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result Result { @@ -335,13 +336,14 @@ fn on_packet_failure( ]; let amount = Amount::from_parts(msg.denom, msg.amount); - let msg = send_amount(amount, msg.sender); + let gas_limit = check_gas_limit(deps.as_ref(), &amount)?; + let msg = send_amount(amount, msg.sender, gas_limit); Ok(IbcBasicResponse::new() .add_attributes(attributes) .add_submessage(msg)) } -fn send_amount(amount: Amount, recipient: String) -> SubMsg { +fn send_amount(amount: Amount, recipient: String, gas_limit: Option) -> SubMsg { match amount { Amount::Native(coin) => SubMsg::reply_on_error( BankMsg::Send { @@ -360,7 +362,9 @@ fn send_amount(amount: Amount, recipient: String) -> SubMsg { msg: to_binary(&msg).unwrap(), funds: vec![], }; - SubMsg::reply_on_error(exec, SEND_TOKEN_ID) + let mut sub = SubMsg::reply_on_error(exec, SEND_TOKEN_ID); + sub.gas_limit = gas_limit; + sub } } } @@ -401,7 +405,12 @@ mod test { assert_eq!(expected, encdoded.as_str()); } - fn cw20_payment(amount: u128, address: &str, recipient: &str) -> SubMsg { + fn cw20_payment( + amount: u128, + address: &str, + recipient: &str, + gas_limit: Option, + ) -> SubMsg { let msg = Cw20ExecuteMsg::Transfer { recipient: recipient.into(), amount: Uint128::new(amount), @@ -411,7 +420,9 @@ mod test { msg: to_binary(&msg).unwrap(), funds: vec![], }; - SubMsg::reply_on_error(exec, SEND_TOKEN_ID) + let mut msg = SubMsg::reply_on_error(exec, SEND_TOKEN_ID); + msg.gas_limit = gas_limit; + msg } fn native_payment(amount: u128, denom: &str, recipient: &str) -> SubMsg { @@ -479,9 +490,10 @@ mod test { let send_channel = "channel-9"; let cw20_addr = "token-addr"; let cw20_denom = "cw20:token-addr"; + let gas_limit = 1234567; let mut deps = setup( &["channel-1", "channel-7", send_channel], - &[(cw20_addr, 1234567)], + &[(cw20_addr, gas_limit)], ); // prepare some mock packets @@ -520,7 +532,7 @@ mod test { let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert_eq!(1, res.messages.len()); assert_eq!( - cw20_payment(876543210, cw20_addr, "local-rcpt"), + cw20_payment(876543210, cw20_addr, "local-rcpt", Some(gas_limit)), res.messages[0] ); let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); From 65fcbf56d5372eac4f0047e01daab95af0ec2ce1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 23:29:27 +0100 Subject: [PATCH 161/631] Cleanup --- contracts/cw20-ics20/src/ibc.rs | 53 ++++++++++++++------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 6435dc589..136337456 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -228,24 +228,17 @@ fn do_ibc_packet_receive( let to_send = Amount::from_parts(denom.to_string(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; + let send = send_amount(to_send, msg.receiver.clone(), gas_limit); - // build attributes first so we don't have to clone msg below - // similar event messages like ibctransfer module - - let attributes = vec![ - attr("action", "receive"), - attr("sender", &msg.sender), - attr("receiver", &msg.receiver), - attr("denom", denom), - attr("amount", msg.amount), - attr("success", "true"), - ]; - - let msg = send_amount(to_send, msg.receiver, gas_limit); let res = IbcReceiveResponse::new() .set_ack(ack_success()) - .add_submessage(msg) - .add_attributes(attributes); + .add_submessage(send) + .add_attribute("action", "receive") + .add_attribute("sender", msg.sender) + .add_attribute("receiver", msg.receiver) + .add_attribute("denom", denom) + .add_attribute("amount", msg.amount) + .add_attribute("success", "true"); Ok(res) } @@ -324,23 +317,23 @@ fn on_packet_failure( err: String, ) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; + + let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); + let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; + let send = send_amount(to_send, msg.sender.clone(), gas_limit); + // similar event messages like ibctransfer module - let attributes = vec![ - attr("action", "acknowledge"), - attr("sender", &msg.sender), - attr("receiver", &msg.receiver), - attr("denom", &msg.denom), - attr("amount", &msg.amount.to_string()), - attr("success", "false"), - attr("error", err), - ]; + let res = IbcBasicResponse::new() + .add_submessage(send) + .add_attribute("action", "acknowledge") + .add_attribute("sender", msg.sender) + .add_attribute("receiver", msg.receiver) + .add_attribute("denom", msg.denom) + .add_attribute("amount", msg.amount.to_string()) + .add_attribute("success", "false") + .add_attribute("error", err); - let amount = Amount::from_parts(msg.denom, msg.amount); - let gas_limit = check_gas_limit(deps.as_ref(), &amount)?; - let msg = send_amount(amount, msg.sender, gas_limit); - Ok(IbcBasicResponse::new() - .add_attributes(attributes) - .add_submessage(msg)) + Ok(res) } fn send_amount(amount: Amount, recipient: String, gas_limit: Option) -> SubMsg { From 383963319589cd9d9ba923e380939abd7146f548 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 17 Jan 2022 22:08:50 +0100 Subject: [PATCH 162/631] PR comments --- contracts/cw20-ics20/src/contract.rs | 2 +- contracts/cw20-ics20/src/msg.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 22428f878..8c705bd1f 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -122,7 +122,7 @@ pub fn execute_transfer( ); packet.validate()?; - // prepare message and set proper gas limit + // prepare ibc message let msg = IbcMsg::SendPacket { channel_id: msg.channel, data: to_binary(&packet)?, diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index ddaade744..044cbf2f6 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -49,7 +49,6 @@ pub struct TransferMsg { pub timeout: Option, } -// TODO: query config, query allow list #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { From 759ccc0695feb9e71138a1c30145f0b094a0753d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 21 Jan 2022 13:14:54 +0100 Subject: [PATCH 163/631] Fix tag consolidation for matching CHANGELOG entries --- scripts/update_changelog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_changelog.sh b/scripts/update_changelog.sh index 09331e61e..6b2900615 100755 --- a/scripts/update_changelog.sh +++ b/scripts/update_changelog.sh @@ -44,7 +44,7 @@ echo "Git version tag: $TAG" cp CHANGELOG.md /tmp/CHANGELOG.md.$$ # Consolidate tag for matching changelog entries -TAG=$(echo "$TAG" | sed 's/-\([A-Za-z]*\)[^A-Za-z]*/-\1/') +TAG=$(echo "$TAG" | sed -e 's/-\([A-Za-z]*\)[^A-Za-z]*/-\1/' -e 's/-$//') echo "Consolidated tag: $TAG" sed -i -n "/^## \\[${TAG}[^]]*\\]/,\$p" CHANGELOG.md From 3ae535969ab4125adf811eee6b74a8690950ac73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 25 Jan 2022 20:14:28 +0300 Subject: [PATCH 164/631] Refactor cw2 spec readme I think removing migration reference cw2 spec makes sense. This spec is used for code inspection and verification too. Migration name in the title makes it hard for someone to find this. --- packages/cw2/README.md | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/packages/cw2/README.md b/packages/cw2/README.md index dec9f09ef..3d1e31781 100644 --- a/packages/cw2/README.md +++ b/packages/cw2/README.md @@ -1,21 +1,28 @@ -# CW2 Spec: Contract Info for Migration +# CW2 Spec: Contract Info Most of the CW* specs are focused on the *public interfaces* of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. -However, when we wish to migrate from contract A to contract B, -contract B needs to be aware somehow of how the *state was encoded*. +However, when we wish to migrate or inspect smart contract info, +we need some form of smart contract information embedded on state. -Generally we use Singletons and Buckets to store the state, but -if I upgrade to a `cw20-with-bonding-curve` contract, it will only -work properly if I am migrating from a `cw20-base` contract. But how -can the new contract know what format the data was stored. +This is where CW2 comes in. It specifies on special Item to +be stored on disk by all contracts on `instantiate`. -This is where CW2 comes in. It specifies on special Singleton to -be stored on disk by all contracts on `instantiate`. When the `migrate` -function is called, then the new contract can read that data and -see if this is an expected contract we can migrate from. And also -contain extra version information if we support multiple migrate -paths. +`ContractInfo` is must be stored under `"contract_info"` key which translates +to `"636F6E74726163745F696E666F"` in hex format. +Since the state is well defined, we do not need to support any "smart queries". +We do provide a helper to construct a "raw query" to read the ContractInfo +of any CW2-compliant contract. + +You can query using: +```shell +wasmd query wasm contract-state raw [contract_addr] 636F6E74726163745F696E666F --node $RPC +``` + +When the `migrate` function is called, then the new contract +can read that data andsee if this is an expected contract we can +migrate from. And also contain extra version information if we +support multiple migrate paths. ### Data structures @@ -49,9 +56,3 @@ Thus, an serialized example may looks like: "version": "v0.1.0" } ``` - -### Queries - -Since the state is well defined, we do not need to support any "smart queries". -We do provide a helper to construct a "raw query" to read the ContractInfo -of any CW2-compliant contract. From 7cdf2d127b2b50c148282a6712b6e72edea5813d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 27 Jan 2022 10:10:32 +0100 Subject: [PATCH 165/631] Update rust to v0.44.0 in CI --- .circleci/config.yml | 140 +++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bccf2c4b3..79b005986 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,7 +52,7 @@ workflows: jobs: contract_cw1_subkeys: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist_ng: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-ng-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-ng-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1155_base: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1155-base-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1155-base-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_controllers: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-controllers:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-controllers:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_utils: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-utils:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-utils:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw2: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw2:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw2:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.54.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.54.0-{{ 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.53.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.54.0-{{ 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.53.0 + - image: rust:1.54.0 steps: - checkout: path: ~/project @@ -582,7 +582,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.54.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: | @@ -614,7 +614,7 @@ jobs: package_multi_test: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-multi-test:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-multi-test:1.54.0-{{ checksum "~/project/Cargo.lock" }} package_storage_plus: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 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.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-storage-plus:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-storage-plus:1.54.0-{{ checksum "~/project/Cargo.lock" }} benchmarking: docker: - - image: rust:1.53.0 + - image: rust:1.54.0 environment: RUST_BACKTRACE: 1 steps: @@ -684,7 +684,7 @@ jobs: command: rustc --version && cargo --version - restore_cache: keys: - - cargocache-v2-benchmarking-rust:1.53.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-benchmarking-rust:1.54.0-{{ 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.53.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-benchmarking-rust:1.54.0-{{ 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.53.0 + - image: rust:1.54.0 working_directory: ~/project steps: - checkout: From 0431c3056fc02ec332d6ffcb26c59dd703932fe4 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Thu, 27 Jan 2022 10:27:26 +0100 Subject: [PATCH 166/631] Remove needless borrow after rust update --- contracts/cw1-whitelist-ng/src/contract.rs | 24 +++++++++---------- contracts/cw1-whitelist/src/contract.rs | 20 ++++++++-------- contracts/cw4-stake/src/contract.rs | 2 +- packages/multi-test/src/app.rs | 2 +- packages/multi-test/src/wasm.rs | 2 +- packages/storage-plus/src/indexed_snapshot.rs | 2 +- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/contracts/cw1-whitelist-ng/src/contract.rs b/contracts/cw1-whitelist-ng/src/contract.rs index 301b20c96..177b30034 100644 --- a/contracts/cw1-whitelist-ng/src/contract.rs +++ b/contracts/cw1-whitelist-ng/src/contract.rs @@ -223,7 +223,7 @@ mod tests { // instantiate the contract let admins = vec![alice.to_owned(), bob.to_owned(), carl.to_owned()]; - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); contract .instantiate(deps.as_mut(), mock_env(), info, admins, true) .unwrap(); @@ -239,7 +239,7 @@ mod tests { ); // anyone cannot modify the contract - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); let err = contract .update_admins(deps.as_mut(), mock_env(), info, vec![anyone.to_owned()]) .unwrap_err(); @@ -247,7 +247,7 @@ mod tests { // but alice can kick out carl let admins = vec![alice.to_owned(), bob.to_owned()]; - let info = mock_info(&alice, &[]); + let info = mock_info(alice, &[]); contract .update_admins(deps.as_mut(), mock_env(), info, admins) .unwrap(); @@ -263,14 +263,14 @@ mod tests { ); // carl cannot freeze it - let info = mock_info(&carl, &[]); + let info = mock_info(carl, &[]); let err = contract .freeze(deps.as_mut(), mock_env(), info) .unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but bob can - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); contract.freeze(deps.as_mut(), mock_env(), info).unwrap(); let expected = AdminListResponse { admins: vec![alice.to_owned(), bob.to_owned()], @@ -282,7 +282,7 @@ mod tests { ); // and now alice cannot change it again - let info = mock_info(&alice, &[]); + let info = mock_info(alice, &[]); let err = contract .update_admins(deps.as_mut(), mock_env(), info, vec![alice.to_owned()]) .unwrap_err(); @@ -300,7 +300,7 @@ mod tests { // instantiate the contract let admins = vec![alice.to_owned(), carl.to_owned()]; - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); contract .instantiate(deps.as_mut(), mock_env(), info, admins, false) .unwrap(); @@ -321,14 +321,14 @@ mod tests { ]; // bob cannot execute them - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); let err = contract .execute(deps.as_mut(), mock_env(), info, msgs.clone()) .unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but carl can - let info = mock_info(&carl, &[]); + let info = mock_info(carl, &[]); let res = contract .execute(deps.as_mut(), mock_env(), info, msgs.clone()) .unwrap(); @@ -346,7 +346,7 @@ mod tests { let alice = "alice"; let admins = vec![alice.to_owned()]; - let info = mock_info(&alice, &[]); + let info = mock_info(alice, &[]); contract .instantiate(deps.as_mut(), mock_env(), info, admins, false) .unwrap(); @@ -357,7 +357,7 @@ mod tests { .execute( deps.as_mut(), mock_env(), - mock_info(&alice, &[]), + mock_info(alice, &[]), msgs.clone(), ) .unwrap(); @@ -380,7 +380,7 @@ mod tests { // instantiate the contract let admins = vec![alice.to_owned(), bob.to_owned()]; - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); contract .instantiate(deps.as_mut(), mock_env(), info, admins, false) .unwrap(); diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index c7c8784fb..77f2b7ef7 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -162,7 +162,7 @@ mod tests { admins: vec![alice.to_string(), bob.to_string(), carl.to_string()], mutable: true, }; - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); // ensure expected config @@ -176,7 +176,7 @@ mod tests { let msg = ExecuteMsg::UpdateAdmins { admins: vec![anyone.to_string()], }; - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); @@ -184,7 +184,7 @@ mod tests { let msg = ExecuteMsg::UpdateAdmins { admins: vec![alice.to_string(), bob.to_string()], }; - let info = mock_info(&alice, &[]); + let info = mock_info(alice, &[]); execute(deps.as_mut(), mock_env(), info, msg).unwrap(); // ensure expected config @@ -195,12 +195,12 @@ mod tests { assert_eq!(query_admin_list(deps.as_ref()).unwrap(), expected); // carl cannot freeze it - let info = mock_info(&carl, &[]); + let info = mock_info(carl, &[]); let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Freeze {}).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but bob can - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Freeze {}).unwrap(); let expected = AdminListResponse { admins: vec![alice.to_string(), bob.to_string()], @@ -212,7 +212,7 @@ mod tests { let msg = ExecuteMsg::UpdateAdmins { admins: vec![alice.to_string()], }; - let info = mock_info(&alice, &[]); + let info = mock_info(alice, &[]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); } @@ -230,7 +230,7 @@ mod tests { admins: vec![alice.to_string(), carl.to_string()], mutable: false, }; - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); let freeze: ExecuteMsg = ExecuteMsg::Freeze {}; @@ -252,12 +252,12 @@ mod tests { let execute_msg = ExecuteMsg::Execute { msgs: msgs.clone() }; // bob cannot execute them - let info = mock_info(&bob, &[]); + let info = mock_info(bob, &[]); let err = execute(deps.as_mut(), mock_env(), info, execute_msg.clone()).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but carl can - let info = mock_info(&carl, &[]); + let info = mock_info(carl, &[]); let res = execute(deps.as_mut(), mock_env(), info, execute_msg).unwrap(); assert_eq!( res.messages, @@ -280,7 +280,7 @@ mod tests { admins: vec![alice.to_string(), bob.to_string()], mutable: false, }; - let info = mock_info(&anyone, &[]); + let info = mock_info(anyone, &[]); instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); // let us make some queries... different msg types by owner and by other diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index e1d372083..f57be9b9b 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -669,7 +669,7 @@ mod tests { }) => { assert_eq!(contract_addr.as_str(), CW20_ADDRESS); assert_eq!(funds.len(), 0); - let parsed: Cw20ExecuteMsg = from_slice(&msg).unwrap(); + let parsed: Cw20ExecuteMsg = from_slice(msg).unwrap(); assert_eq!( parsed, Cw20ExecuteMsg::Transfer { diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 326d54587..c23e6873a 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -924,7 +924,7 @@ where Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {}", e.to_string()), + error: format!("Parsing query request: {}", e), request: bin_request.into(), }) } diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 56279925b..49646d876 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -798,7 +798,7 @@ where .range_raw(storage, None, None, Order::Ascending) .count(); // we make this longer so it is not rejected by tests - Addr::unchecked(format!("Contract #{}", count.to_string())) + Addr::unchecked(format!("Contract #{}", count)) } fn contract_namespace(&self, contract: &Addr) -> Vec { diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 8476572bd..e5f45bfa2 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -58,7 +58,7 @@ impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> { } pub fn changelog(&self) -> &Map<'a, (K, u64), ChangeSet> { - &self.primary.changelog() + self.primary.changelog() } } From a1c4642a7f4af10861d12c154f2007efe6e86164 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Thu, 27 Jan 2022 10:49:28 +0100 Subject: [PATCH 167/631] Update check contract's job cosmwasm to beta4 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79b005986..c991d2dd6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -597,7 +597,7 @@ jobs: - run: name: Install check_contract # Uses --debug for compilation speed - command: cargo install --debug --version 1.0.0-beta --features iterator --example check_contract -- cosmwasm-vm + command: cargo install --debug --version 1.0.0-beta4 --features iterator --example check_contract -- cosmwasm-vm - save_cache: paths: - /usr/local/cargo/registry From 1d7a0a17cd82c03c0c03ff27ef737de8a3583005 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 15 Jan 2022 23:40:46 +0100 Subject: [PATCH 168/631] Start handling rollback on submessage error --- contracts/cw20-ics20/src/ibc.rs | 41 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 136337456..de633b9fb 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -72,21 +72,25 @@ fn ack_fail(err: String) -> Binary { to_binary(&res).unwrap() } -const SEND_TOKEN_ID: u64 = 1337; +const RECEIVE_ID: u64 = 1337; +const ACK_FAILURE_ID: u64 = 0xfa17; #[cfg_attr(not(feature = "library"), entry_point)] pub fn reply(_deps: DepsMut, _env: Env, reply: Reply) -> Result { - if reply.id != SEND_TOKEN_ID { - return Err(ContractError::UnknownReplyId { id: reply.id }); - } - let res = match reply.result { - ContractResult::Ok(_) => Response::new(), + match reply.result { + ContractResult::Ok(_) => Ok(Response::new()), ContractResult::Err(err) => { - // encode an acknowledgement error - Response::new().set_data(ack_fail(err)) + let res = Response::new().set_data(ack_fail(err)); + match reply.id { + RECEIVE_ID => { + // TODO: revert state change + Ok(res) + } + ACK_FAILURE_ID => Ok(res), + _ => Err(ContractError::UnknownReplyId { id: reply.id }), + } } - }; - Ok(res) + } } #[cfg_attr(not(feature = "library"), entry_point)] @@ -212,6 +216,9 @@ fn do_ibc_packet_receive( // If it originated on our chain, it looks like "port/channel/ucosm". let denom = parse_voucher_denom(&msg.denom, &packet.src)?; + // Important design note: with ibcv2 and wasmd 0.22 we should return error so this gets reverted + // If we need compatibility with Juno (Jan 2022), we need to ensure that this state change gets reverted + // in the case of the submessage (transfer) erroring CHANNEL_STATE.update( deps.storage, (&channel, denom), @@ -228,7 +235,7 @@ fn do_ibc_packet_receive( let to_send = Amount::from_parts(denom.to_string(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; - let send = send_amount(to_send, msg.receiver.clone(), gas_limit); + let send = send_amount(to_send, msg.receiver.clone(), gas_limit, RECEIVE_ID); let res = IbcReceiveResponse::new() .set_ack(ack_success()) @@ -320,7 +327,7 @@ fn on_packet_failure( let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; - let send = send_amount(to_send, msg.sender.clone(), gas_limit); + let send = send_amount(to_send, msg.sender.clone(), gas_limit, ACK_FAILURE_ID); // similar event messages like ibctransfer module let res = IbcBasicResponse::new() @@ -336,14 +343,14 @@ fn on_packet_failure( Ok(res) } -fn send_amount(amount: Amount, recipient: String, gas_limit: Option) -> SubMsg { +fn send_amount(amount: Amount, recipient: String, gas_limit: Option, reply_id: u64) -> SubMsg { match amount { Amount::Native(coin) => SubMsg::reply_on_error( BankMsg::Send { to_address: recipient, amount: vec![coin], }, - SEND_TOKEN_ID, + reply_id, ), Amount::Cw20(coin) => { let msg = Cw20ExecuteMsg::Transfer { @@ -355,7 +362,7 @@ fn send_amount(amount: Amount, recipient: String, gas_limit: Option) -> Sub msg: to_binary(&msg).unwrap(), funds: vec![], }; - let mut sub = SubMsg::reply_on_error(exec, SEND_TOKEN_ID); + let mut sub = SubMsg::reply_on_error(exec, reply_id); sub.gas_limit = gas_limit; sub } @@ -413,7 +420,7 @@ mod test { msg: to_binary(&msg).unwrap(), funds: vec![], }; - let mut msg = SubMsg::reply_on_error(exec, SEND_TOKEN_ID); + let mut msg = SubMsg::reply_on_error(exec, RECEIVE_ID); msg.gas_limit = gas_limit; msg } @@ -424,7 +431,7 @@ mod test { to_address: recipient.into(), amount: coins(amount, denom), }, - SEND_TOKEN_ID, + RECEIVE_ID, ) } From 2803a9806b26df651f390d9462f5decb877f8352 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sun, 16 Jan 2022 00:10:59 +0100 Subject: [PATCH 169/631] Only make state changes when submessages pass --- contracts/cw20-ics20/src/ibc.rs | 132 ++++++++++++++++-------------- contracts/cw20-ics20/src/state.rs | 50 ++++++++++- 2 files changed, 119 insertions(+), 63 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index de633b9fb..cf69993b7 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -2,15 +2,18 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{ - attr, entry_point, from_binary, to_binary, BankMsg, Binary, ContractResult, Deps, DepsMut, Env, - IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, - IbcReceiveResponse, Reply, Response, StdResult, SubMsg, Uint128, WasmMsg, + attr, entry_point, from_binary, to_binary, BankMsg, Binary, ContractResult, CosmosMsg, Deps, + DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, + IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, + IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, SubMsg, Uint128, WasmMsg, }; use crate::amount::Amount; use crate::error::{ContractError, Never}; -use crate::state::{ChannelInfo, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE}; +use crate::state::{ + increase_channel_balance, reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, + CHANNEL_INFO, REPLY_ARGS, +}; use cw20::Cw20ExecuteMsg; pub const ICS20_VERSION: &str = "ics20-1"; @@ -76,20 +79,39 @@ const RECEIVE_ID: u64 = 1337; const ACK_FAILURE_ID: u64 = 0xfa17; #[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(_deps: DepsMut, _env: Env, reply: Reply) -> Result { - match reply.result { - ContractResult::Ok(_) => Ok(Response::new()), - ContractResult::Err(err) => { - let res = Response::new().set_data(ack_fail(err)); - match reply.id { - RECEIVE_ID => { - // TODO: revert state change - Ok(res) - } - ACK_FAILURE_ID => Ok(res), - _ => Err(ContractError::UnknownReplyId { id: reply.id }), +pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> Result { + match reply.id { + RECEIVE_ID => match reply.result { + ContractResult::Ok(_) => { + // Important design note: with ibcv2 and wasmd 0.22 we can implement this all much easier. + // No reply needed... the receive function and submessage should return error on failure and all + // state gets reverted with a proper app-level message auto-generated + + // Since we need compatibility with Juno (Jan 2022), we need to ensure that no state gets written + // if the receive processing succeeds, but the submesage fails, so we can only write after we are + // sure all submessages succeeded. + + // However, this requires passing some state between the ibc_packet_receive function and + // the reply handler. We do this with a singleton, with is "okay" for IBC as there is no + // reentrancy on these functions (cannot be called by another contract). This pattern + // should not be used for ExecuteMsg handlers + let reply_args = REPLY_ARGS.load(deps.storage)?; + reduce_channel_balance( + deps.storage, + &reply_args.channel, + &reply_args.denom, + reply_args.amount, + )?; + + Ok(Response::new()) } - } + ContractResult::Err(err) => Ok(Response::new().set_data(ack_fail(err))), + }, + ACK_FAILURE_ID => match reply.result { + ContractResult::Ok(_) => Ok(Response::new()), + ContractResult::Err(err) => Ok(Response::new().set_data(ack_fail(err))), + }, + _ => Err(ContractError::UnknownReplyId { id: reply.id }), } } @@ -216,30 +238,23 @@ fn do_ibc_packet_receive( // If it originated on our chain, it looks like "port/channel/ucosm". let denom = parse_voucher_denom(&msg.denom, &packet.src)?; - // Important design note: with ibcv2 and wasmd 0.22 we should return error so this gets reverted - // If we need compatibility with Juno (Jan 2022), we need to ensure that this state change gets reverted - // in the case of the submessage (transfer) erroring - CHANNEL_STATE.update( - deps.storage, - (&channel, denom), - |orig| -> Result<_, ContractError> { - // this will return error if we don't have the funds there to cover the request (or no denom registered) - let mut cur = orig.ok_or(ContractError::InsufficientFunds {})?; - cur.outstanding = cur - .outstanding - .checked_sub(msg.amount) - .or(Err(ContractError::InsufficientFunds {}))?; - Ok(cur) - }, - )?; + // we need to save the data to update the balances in reply + let reply_args = ReplyArgs { + channel, + denom: denom.to_string(), + amount: msg.amount, + }; + REPLY_ARGS.save(deps.storage, &reply_args)?; let to_send = Amount::from_parts(denom.to_string(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; - let send = send_amount(to_send, msg.receiver.clone(), gas_limit, RECEIVE_ID); + let send = send_amount(to_send, msg.receiver.clone()); + let mut submsg = SubMsg::reply_always(send, RECEIVE_ID); + submsg.gas_limit = gas_limit; let res = IbcReceiveResponse::new() .set_ack(ack_success()) - .add_submessage(send) + .add_submessage(submsg) .add_attribute("action", "receive") .add_attribute("sender", msg.sender) .add_attribute("receiver", msg.receiver) @@ -271,7 +286,9 @@ pub fn ibc_packet_ack( _env: Env, msg: IbcPacketAckMsg, ) -> Result { - // TODO: trap error like in receive? + // Design decision: should we trap error like in receive? + // TODO: unsure... as it is now a failed ack handling would revert the tx and would be + // retried again and again. is that good? let ics20msg: Ics20Ack = from_binary(&msg.acknowledgement.data)?; match ics20msg { Ics20Ack::Result(_) => on_packet_success(deps, msg.original_packet), @@ -286,7 +303,7 @@ pub fn ibc_packet_timeout( _env: Env, msg: IbcPacketTimeoutMsg, ) -> Result { - // TODO: trap error like in receive? + // TODO: trap error like in receive? (same question as ack above) let packet = msg.packet; on_packet_failure(deps, packet, "timeout".to_string()) } @@ -304,15 +321,8 @@ fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result StdResult<_> { - let mut state = orig.unwrap_or_default(); - state.outstanding += amount; - state.total_sent += amount; - Ok(state) - })?; + // we have made a proper transfer, record this + increase_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; Ok(IbcBasicResponse::new().add_attributes(attributes)) } @@ -327,11 +337,13 @@ fn on_packet_failure( let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; - let send = send_amount(to_send, msg.sender.clone(), gas_limit, ACK_FAILURE_ID); + let send = send_amount(to_send, msg.sender.clone()); + let mut submsg = SubMsg::reply_on_error(send, ACK_FAILURE_ID); + submsg.gas_limit = gas_limit; // similar event messages like ibctransfer module let res = IbcBasicResponse::new() - .add_submessage(send) + .add_submessage(submsg) .add_attribute("action", "acknowledge") .add_attribute("sender", msg.sender) .add_attribute("receiver", msg.receiver) @@ -343,28 +355,24 @@ fn on_packet_failure( Ok(res) } -fn send_amount(amount: Amount, recipient: String, gas_limit: Option, reply_id: u64) -> SubMsg { +fn send_amount(amount: Amount, recipient: String) -> CosmosMsg { match amount { - Amount::Native(coin) => SubMsg::reply_on_error( - BankMsg::Send { - to_address: recipient, - amount: vec![coin], - }, - reply_id, - ), + Amount::Native(coin) => BankMsg::Send { + to_address: recipient, + amount: vec![coin], + } + .into(), Amount::Cw20(coin) => { let msg = Cw20ExecuteMsg::Transfer { recipient, amount: coin.amount, }; - let exec = WasmMsg::Execute { + WasmMsg::Execute { contract_addr: coin.address, msg: to_binary(&msg).unwrap(), funds: vec![], - }; - let mut sub = SubMsg::reply_on_error(exec, reply_id); - sub.gas_limit = gas_limit; - sub + } + .into() } } } diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index b87307a65..37e8874b3 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -1,11 +1,15 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, IbcEndpoint, Uint128}; +use crate::ContractError; +use cosmwasm_std::{Addr, IbcEndpoint, StdResult, Storage, Uint128}; use cw_storage_plus::{Item, Map}; pub const CONFIG: Item = Item::new("ics20_config"); +// Used to pass info from the ibc_packet_receive to the reply handler +pub const REPLY_ARGS: Item = Item::new("reply_args"); + /// static info on one channel that doesn't change pub const CHANNEL_INFO: Map<&str, ChannelInfo> = Map::new("channel_info"); @@ -41,3 +45,47 @@ pub struct ChannelInfo { pub struct AllowInfo { pub gas_limit: Option, } + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct ReplyArgs { + pub channel: String, + pub denom: String, + pub amount: Uint128, +} + +pub fn reduce_channel_balance( + storage: &mut dyn Storage, + channel: &str, + denom: &str, + amount: Uint128, +) -> Result<(), ContractError> { + CHANNEL_STATE.update( + storage, + (channel, denom), + |orig| -> Result<_, ContractError> { + // this will return error if we don't have the funds there to cover the request (or no denom registered) + let mut cur = orig.ok_or(ContractError::InsufficientFunds {})?; + cur.outstanding = cur + .outstanding + .checked_sub(amount) + .or(Err(ContractError::InsufficientFunds {}))?; + Ok(cur) + }, + )?; + Ok(()) +} + +pub fn increase_channel_balance( + storage: &mut dyn Storage, + channel: &str, + denom: &str, + amount: Uint128, +) -> Result<(), ContractError> { + CHANNEL_STATE.update(storage, (channel, denom), |orig| -> StdResult<_> { + let mut state = orig.unwrap_or_default(); + state.outstanding += amount; + state.total_sent += amount; + Ok(state) + })?; + Ok(()) +} From 978afcd88ccc25d9c35eee140722d54c4d0e3d5d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sun, 16 Jan 2022 00:18:52 +0100 Subject: [PATCH 170/631] Logic should be properly implemented, need to call reply in mock tests --- contracts/cw20-ics20/src/ibc.rs | 15 +++++++++++---- contracts/cw20-ics20/src/state.rs | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index cf69993b7..fc993beff 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -11,8 +11,8 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ - increase_channel_balance, reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, - CHANNEL_INFO, REPLY_ARGS, + ensure_channel_balance, increase_channel_balance, reduce_channel_balance, ChannelInfo, + ReplyArgs, ALLOW_LIST, CHANNEL_INFO, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -238,6 +238,9 @@ fn do_ibc_packet_receive( // If it originated on our chain, it looks like "port/channel/ucosm". let denom = parse_voucher_denom(&msg.denom, &packet.src)?; + // make sure we have enough balance for this (that is, the later reduction in the reply handler should succeed) + ensure_channel_balance(deps.storage, &channel, denom, msg.amount)?; + // we need to save the data to update the balances in reply let reply_args = ReplyArgs { channel, @@ -428,13 +431,13 @@ mod test { msg: to_binary(&msg).unwrap(), funds: vec![], }; - let mut msg = SubMsg::reply_on_error(exec, RECEIVE_ID); + let mut msg = SubMsg::reply_always(exec, RECEIVE_ID); msg.gas_limit = gas_limit; msg } fn native_payment(amount: u128, denom: &str, recipient: &str) -> SubMsg { - SubMsg::reply_on_error( + SubMsg::reply_always( BankMsg::Send { to_address: recipient.into(), amount: coins(amount, denom), @@ -546,6 +549,8 @@ mod test { let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); matches!(ack, Ics20Ack::Result(_)); + // TODO: we need to call the reply block + // query channel state let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); assert_eq!(state.balances, vec![Amount::cw20(111111111, cw20_addr)]); @@ -600,6 +605,8 @@ mod test { let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); matches!(ack, Ics20Ack::Result(_)); + // TODO: we must call the reply block + // query channel state let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); assert_eq!(state.balances, vec![Amount::native(111111111, denom)]); diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 37e8874b3..7f455beca 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -53,6 +53,23 @@ pub struct ReplyArgs { pub amount: Uint128, } +// this is like reduce_channel_balance, but doesn't change the state +// it returns an error IFF reduce_channel_balance would return an error +pub fn ensure_channel_balance( + storage: &dyn Storage, + channel: &str, + denom: &str, + amount: Uint128, +) -> Result<(), ContractError> { + CHANNEL_STATE + .may_load(storage, (channel, denom))? + .ok_or(ContractError::InsufficientFunds {})? + .outstanding + .checked_sub(amount) + .map_err(|_| ContractError::InsufficientFunds {})?; + Ok(()) +} + pub fn reduce_channel_balance( storage: &mut dyn Storage, channel: &str, From 315be1af1e8da84692fec49e5cfaa9fc4f4e9c1e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 27 Jan 2022 20:35:53 +0100 Subject: [PATCH 171/631] Update state on receive, undo on submessage error --- contracts/cw20-ics20/src/ibc.rs | 18 +++++++++--------- contracts/cw20-ics20/src/state.rs | 23 +++++++++++------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index fc993beff..a05fc0023 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -11,7 +11,7 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ - ensure_channel_balance, increase_channel_balance, reduce_channel_balance, ChannelInfo, + increase_channel_balance, reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, CHANNEL_INFO, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -82,30 +82,30 @@ const ACK_FAILURE_ID: u64 = 0xfa17; pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> Result { match reply.id { RECEIVE_ID => match reply.result { - ContractResult::Ok(_) => { + ContractResult::Ok(_) => Ok(Response::new()), + ContractResult::Err(err) => { // Important design note: with ibcv2 and wasmd 0.22 we can implement this all much easier. // No reply needed... the receive function and submessage should return error on failure and all // state gets reverted with a proper app-level message auto-generated - // Since we need compatibility with Juno (Jan 2022), we need to ensure that no state gets written - // if the receive processing succeeds, but the submesage fails, so we can only write after we are - // sure all submessages succeeded. + // Since we need compatibility with Juno (Jan 2022), we need to ensure that optimisitic + // state updates in ibc_packet_receive get reverted in the (unlikely) chance of an + // error while sending the token // However, this requires passing some state between the ibc_packet_receive function and // the reply handler. We do this with a singleton, with is "okay" for IBC as there is no // reentrancy on these functions (cannot be called by another contract). This pattern // should not be used for ExecuteMsg handlers let reply_args = REPLY_ARGS.load(deps.storage)?; - reduce_channel_balance( + undo_reduce_channel_balance( deps.storage, &reply_args.channel, &reply_args.denom, reply_args.amount, )?; - Ok(Response::new()) + Ok(Response::new().set_data(ack_fail(err))) } - ContractResult::Err(err) => Ok(Response::new().set_data(ack_fail(err))), }, ACK_FAILURE_ID => match reply.result { ContractResult::Ok(_) => Ok(Response::new()), @@ -239,7 +239,7 @@ fn do_ibc_packet_receive( let denom = parse_voucher_denom(&msg.denom, &packet.src)?; // make sure we have enough balance for this (that is, the later reduction in the reply handler should succeed) - ensure_channel_balance(deps.storage, &channel, denom, msg.amount)?; + reduce_channel_balance(deps.storage, &channel, denom, msg.amount)?; // we need to save the data to update the balances in reply let reply_args = ReplyArgs { diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 7f455beca..79c127d8c 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -53,20 +53,18 @@ pub struct ReplyArgs { pub amount: Uint128, } -// this is like reduce_channel_balance, but doesn't change the state -// it returns an error IFF reduce_channel_balance would return an error -pub fn ensure_channel_balance( - storage: &dyn Storage, +pub fn increase_channel_balance( + storage: &mut dyn Storage, channel: &str, denom: &str, amount: Uint128, ) -> Result<(), ContractError> { - CHANNEL_STATE - .may_load(storage, (channel, denom))? - .ok_or(ContractError::InsufficientFunds {})? - .outstanding - .checked_sub(amount) - .map_err(|_| ContractError::InsufficientFunds {})?; + CHANNEL_STATE.update(storage, (channel, denom), |orig| -> StdResult<_> { + let mut state = orig.unwrap_or_default(); + state.outstanding += amount; + state.total_sent += amount; + Ok(state) + })?; Ok(()) } @@ -92,7 +90,9 @@ pub fn reduce_channel_balance( Ok(()) } -pub fn increase_channel_balance( +// this is like increase, but it only "un-subtracts" (= adds) outstanding, not total_sent +// calling `reduce_channel_balance` and then `undo_reduce_channel_balance` should leave state unchanged. +pub fn undo_reduce_channel_balance( storage: &mut dyn Storage, channel: &str, denom: &str, @@ -101,7 +101,6 @@ pub fn increase_channel_balance( CHANNEL_STATE.update(storage, (channel, denom), |orig| -> StdResult<_> { let mut state = orig.unwrap_or_default(); state.outstanding += amount; - state.total_sent += amount; Ok(state) })?; Ok(()) From a0ca1dcc4bb8d8a06a9e4b788a30f261a659b16b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 27 Jan 2022 20:40:43 +0100 Subject: [PATCH 172/631] reply_on_error not always --- contracts/cw20-ics20/src/ibc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index a05fc0023..ebc3139cb 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -238,7 +238,7 @@ fn do_ibc_packet_receive( // If it originated on our chain, it looks like "port/channel/ucosm". let denom = parse_voucher_denom(&msg.denom, &packet.src)?; - // make sure we have enough balance for this (that is, the later reduction in the reply handler should succeed) + // make sure we have enough balance for this reduce_channel_balance(deps.storage, &channel, denom, msg.amount)?; // we need to save the data to update the balances in reply @@ -252,7 +252,7 @@ fn do_ibc_packet_receive( let to_send = Amount::from_parts(denom.to_string(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; let send = send_amount(to_send, msg.receiver.clone()); - let mut submsg = SubMsg::reply_always(send, RECEIVE_ID); + let mut submsg = SubMsg::reply_on_error(send, RECEIVE_ID); submsg.gas_limit = gas_limit; let res = IbcReceiveResponse::new() @@ -431,13 +431,13 @@ mod test { msg: to_binary(&msg).unwrap(), funds: vec![], }; - let mut msg = SubMsg::reply_always(exec, RECEIVE_ID); + let mut msg = SubMsg::reply_on_error(exec, RECEIVE_ID); msg.gas_limit = gas_limit; msg } fn native_payment(amount: u128, denom: &str, recipient: &str) -> SubMsg { - SubMsg::reply_always( + SubMsg::reply_on_error( BankMsg::Send { to_address: recipient.into(), amount: coins(amount, denom), From b84dc61f9dce166f4ea3ccbd096a52ad3c73d843 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 08:23:28 +0100 Subject: [PATCH 173/631] Fix remove_hook helper --- packages/cw4/src/helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cw4/src/helpers.rs b/packages/cw4/src/helpers.rs index 93514a36c..c692f29e7 100644 --- a/packages/cw4/src/helpers.rs +++ b/packages/cw4/src/helpers.rs @@ -43,7 +43,7 @@ impl Cw4Contract { } pub fn remove_hook>(&self, addr: T) -> StdResult { - let msg = Cw4ExecuteMsg::AddHook { addr: addr.into() }; + let msg = Cw4ExecuteMsg::RemoveHook { addr: addr.into() }; self.encode_msg(msg) } From 95593735b7bad451e029e885f46538d9c219bec6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 6 Jan 2022 15:06:55 +0100 Subject: [PATCH 174/631] 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 175/631] 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 176/631] 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 177/631] 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 178/631] 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 179/631] 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 180/631] 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 181/631] 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 182/631] 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 183/631] 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 184/631] 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 185/631] 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 186/631] 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 187/631] 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 188/631] 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 189/631] 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 190/631] 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 191/631] 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 192/631] 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 193/631] 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 194/631] 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 195/631] 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 196/631] 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 197/631] 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 198/631] 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 199/631] 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 200/631] 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 201/631] 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 202/631] 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 203/631] 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: From 5ec0762e1855cf144ba52516717c2c364b05ab70 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 28 Jan 2022 17:22:17 +0100 Subject: [PATCH 204/631] Avoid integer overflows by using math ops with wrapping semantics --- packages/storage-plus/benches/main.rs | 32 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index cd02624c5..1b5e557b1 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -27,12 +27,15 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); + assert_eq!( + to_cw_bytes(&k_check.wrapping_neg()), + i32::to_cw_bytes(&k_check.wrapping_neg()) + ); b.iter(|| { let k = k(); black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&-k)); + black_box(to_cw_bytes(&k.wrapping_neg())); }); }); @@ -44,12 +47,15 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); + assert_eq!( + to_cw_bytes(&k_check.wrapping_neg()), + i32::to_cw_bytes(&k_check.wrapping_neg()) + ); b.iter(|| { let k = k(); black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&-k)); + black_box(to_cw_bytes(&k.wrapping_neg())); }); }); @@ -63,12 +69,15 @@ fn bench_signed_int_key(c: &mut Criterion) { assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); + assert_eq!( + to_cw_bytes(&k_check.wrapping_neg()), + i32::to_cw_bytes(&k_check.wrapping_neg()) + ); b.iter(|| { let k = k(); black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&-k)); + black_box(to_cw_bytes(&k.wrapping_neg())); }); }); @@ -76,20 +85,23 @@ fn bench_signed_int_key(c: &mut Criterion) { #[inline] fn to_cw_bytes(value: &i32) -> Buf { if value >= &0i32 { - (*value as u32 - i32::MIN as u32).to_be_bytes() + ((*value as u32).wrapping_sub(i32::MIN as u32)).to_be_bytes() } else { - (*value as u32 + i32::MIN as u32).to_be_bytes() + ((*value as u32).wrapping_add(i32::MIN as u32)).to_be_bytes() } } assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!(to_cw_bytes(&-k_check), i32::to_cw_bytes(&-k_check)); + assert_eq!( + to_cw_bytes(&k_check.wrapping_neg()), + i32::to_cw_bytes(&k_check.wrapping_neg()) + ); b.iter(|| { let k = k(); black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&-k)); + black_box(to_cw_bytes(&k.wrapping_neg())); }); }); From b4dbcb90cc1d5f0d55d16d3e4a069801dbe02c44 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 31 Jan 2022 13:47:45 +0100 Subject: [PATCH 205/631] Set version: 0.12.0-alpha2 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 10 +++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 105 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e241537d7..56eb22914 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -377,7 +377,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "anyhow", "cosmwasm-std", @@ -394,7 +394,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-std", "criterion", @@ -405,7 +405,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -417,7 +417,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "anyhow", "assert_matches", @@ -463,7 +463,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "anyhow", "assert_matches", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -518,7 +518,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -529,7 +529,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -544,7 +544,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -559,7 +559,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -570,7 +570,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -588,7 +588,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -607,7 +607,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.11.1" +version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 7869846bc..6494b5ffa 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw1 = { path = "../../packages/cw1", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.1", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0-alpha2", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.11.1", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0-alpha2", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index bf65ba592..b25c75182 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw1 = { path = "../../packages/cw1", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index bc60dbb54..d2608ff9e 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw1 = { path = "../../packages/cw1", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 9890e29c6..e97d4b92c 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw1155 = { path = "../../packages/cw1155", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw1155 = { path = "../../packages/cw1155", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 070e6c918..acf849c4a 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 61875dcdd..fe31dd250 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,11 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index bc2649280..b3478efdc 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw3 = { path = "../../packages/cw3", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw3 = { path = "../../packages/cw3", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cw20-base = { path = "../cw20-base", version = "0.11.1", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } +cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } +cw20-base = { path = "../cw20-base", version = "0.12.0-alpha2", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 1fc778bd9..0d5c2fa8f 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw3 = { path = "../../packages/cw3", version = "0.11.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.11.1", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw3 = { path = "../../packages/cw3", version = "0.12.0-alpha2" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.0-alpha2", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw4-group = { path = "../cw4-group", version = "0.11.1" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.11.1" } +cw4-group = { path = "../cw4-group", version = "0.12.0-alpha2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 8f6859053..378fbc7d9 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw4 = { path = "../../packages/cw4", version = "0.11.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index c36847346..a6c662025 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw2 = { path = "../../packages/cw2", version = "0.11.1" } -cw4 = { path = "../../packages/cw4", version = "0.11.1" } -cw20 = { path = "../../packages/cw20", version = "0.11.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } +cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index b2fe7dabd..1c45b919e 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3" } -cw-utils = { path = "../utils", version = "0.11.1" } -cw-storage-plus = { path = "../storage-plus", version = "0.11.1" } +cw-utils = { path = "../utils", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 85f4a0a55..ad9b3130c 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 4f9ded91b..1eae1e014 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 649eb14c9..6acf2984a 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 6675eeca5..a72bf47ec 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 3f6426ff2..9594a1376 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index b87cfbdd6..a7baca6cd 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index f19d84b0d..fdc5b00d7 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.11.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1"} +cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2"} cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta3" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index d2370031d..3f5b57a9d 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index ffc88f5a3..61013d1f0 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.11.1" +version = "0.12.0-alpha2" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.11.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } prost = "0.9" From f23e5c90a3d2dcbe5512079f4eeac29fba38e968 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 31 Jan 2022 20:01:40 +0100 Subject: [PATCH 206/631] flex-multisig: add a double execution test --- contracts/cw3-flex-multisig/src/contract.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 6b31f1071..d901917a9 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1140,9 +1140,23 @@ mod tests { // In passing: Try to close Executed fails let err = app - .execute_contract(Addr::unchecked(OWNER), flex_addr, &closing, &[]) + .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &closing, &[]) .unwrap_err(); assert_eq!(ContractError::WrongCloseStatus {}, err.downcast().unwrap()); + + // Trying to execute something that was already executed fails + let err = app + .execute_contract( + Addr::unchecked(SOMEBODY), + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!( + ContractError::WrongExecuteStatus {}, + err.downcast().unwrap() + ); } #[test] From 3d851e843edf1516fbbbf58b6543261a87685fa8 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 31 Jan 2022 20:28:54 +0100 Subject: [PATCH 207/631] flex-multisig: test executing passed proposal --- contracts/cw3-flex-multisig/src/contract.rs | 81 +++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index d901917a9..1e2840032 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1159,6 +1159,87 @@ mod tests { ); } + #[test] + fn proposal_pass_on_expiration() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = 2000000; + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + Duration::Time(voting_period), + init_funds, + true, + ); + + // ensure we have cash to cover the proposal + let contract_bal = app.wrap().query_balance(&flex_addr, "BTC").unwrap(); + assert_eq!(contract_bal, coin(10, "BTC")); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes after voting period is over + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let res = app + .execute_contract(Addr::unchecked(VOTER3), flex_addr.clone(), &vote, &[]) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER3), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Open"), + ], + ); + + // Wait until the voting period is over. + app.update_block(|block| { + block.time = block.time.plus_seconds(voting_period); + block.height += std::cmp::max(1, voting_period / 5); + }); + + // Proposal should now be passed. + let prop: ProposalResponse = app + .wrap() + .query_wasm_smart(&flex_addr, &QueryMsg::Proposal { proposal_id }) + .unwrap(); + assert_eq!(prop.status, Status::Passed); + + // Execution should now be possible. + let res = app + .execute_contract( + Addr::unchecked(SOMEBODY), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id }, + &[], + ) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "execute"), + ("sender", SOMEBODY), + ("proposal_id", proposal_id.to_string().as_str()), + ], + ); + } + #[test] fn test_close_works() { let init_funds = coins(10, "BTC"); From d3cc69a2221fe9569ba9eca02173c9a51ae4738a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 31 Jan 2022 20:37:52 +0100 Subject: [PATCH 208/631] lints --- contracts/cw3-flex-multisig/src/contract.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 1e2840032..e42855627 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1146,12 +1146,7 @@ mod tests { // Trying to execute something that was already executed fails let err = app - .execute_contract( - Addr::unchecked(SOMEBODY), - flex_addr.clone(), - &execution, - &[], - ) + .execute_contract(Addr::unchecked(SOMEBODY), flex_addr, &execution, &[]) .unwrap_err(); assert_eq!( ContractError::WrongExecuteStatus {}, @@ -1225,7 +1220,7 @@ mod tests { let res = app .execute_contract( Addr::unchecked(SOMEBODY), - flex_addr.clone(), + flex_addr, &ExecuteMsg::Execute { proposal_id }, &[], ) From d139119cff4286b720ba892839fa578bc42b5dcf Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 31 Jan 2022 20:44:38 +0100 Subject: [PATCH 209/631] flex-multisig: fix passed proposal execution --- contracts/cw3-flex-multisig/src/contract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index e42855627..e5444c179 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -188,7 +188,7 @@ pub fn execute_vote( pub fn execute_execute( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, proposal_id: u64, ) -> Result { @@ -197,7 +197,7 @@ pub fn execute_execute( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.status != Status::Passed { + if prop.current_status(&env.block) != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } From 703c007103da65e1d7051a1f76e04bf0abfdec26 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 12:48:56 +0100 Subject: [PATCH 210/631] Replace as_bytes() by into_bytes() --- contracts/cw20-base/src/enumerable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index aa5998d86..7f7991c93 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -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(|s| Bound::ExclusiveRaw(s.as_bytes().into())); + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into_bytes())); let allowances = ALLOWANCES .prefix(&owner_addr) From bc6e804189f1c41d2e64a5e404206b250558e47d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 12:58:28 +0100 Subject: [PATCH 211/631] Update CHANGELOG --- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a835fe6b1..02ba4d208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,48 @@ # Changelog -# Changelog - ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha1...HEAD) + +**Closed issues:** + +- Incorrect Cw4ExecuteMsg used during remove\_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) +- Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) + +**Merged pull requests:** + +- Fix benchmarks \(after 1.58.1 update\) [\#639](https://github.com/CosmWasm/cw-plus/pull/639) ([maurolacy](https://github.com/maurolacy)) +- Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) ([maurolacy](https://github.com/maurolacy)) +- Type safe bounds [\#627](https://github.com/CosmWasm/cw-plus/pull/627) ([maurolacy](https://github.com/maurolacy)) + +## [v0.12.0-alpha1](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha1) (2022-01-27) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...v0.12.0-alpha1) + +**Deprecated:** + +- Remove `IntKey` with surrounding implementation [\#570](https://github.com/CosmWasm/cw-plus/issues/570) + +**Closed issues:** + +- Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) +- Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) + +**Merged pull requests:** + +- Update Rust to v1.54.0 in CI [\#636](https://github.com/CosmWasm/cw-plus/pull/636) ([maurolacy](https://github.com/maurolacy)) +- Refactor cw2 spec readme [\#635](https://github.com/CosmWasm/cw-plus/pull/635) ([orkunkl](https://github.com/orkunkl)) +- Fix tag consolidation for matching CHANGELOG entries [\#634](https://github.com/CosmWasm/cw-plus/pull/634) ([maurolacy](https://github.com/maurolacy)) +- Ics20 contract rollback [\#633](https://github.com/CosmWasm/cw-plus/pull/633) ([ethanfrey](https://github.com/ethanfrey)) +- Fix typo in README.md [\#632](https://github.com/CosmWasm/cw-plus/pull/632) ([josefrichter](https://github.com/josefrichter)) +- Update ics20 contract [\#631](https://github.com/CosmWasm/cw-plus/pull/631) ([ethanfrey](https://github.com/ethanfrey)) +- Publish snapshot map changelog [\#622](https://github.com/CosmWasm/cw-plus/pull/622) ([maurolacy](https://github.com/maurolacy)) +- Remove `IntKey` and `TimestampKey` [\#620](https://github.com/CosmWasm/cw-plus/pull/620) ([ueco-jb](https://github.com/ueco-jb)) +- Signed int key benchmarks [\#619](https://github.com/CosmWasm/cw-plus/pull/619) ([maurolacy](https://github.com/maurolacy)) +- fix readme update coralnet to sandynet-1 [\#617](https://github.com/CosmWasm/cw-plus/pull/617) ([yubrew](https://github.com/yubrew)) +- Publish `PrefixBound` [\#616](https://github.com/CosmWasm/cw-plus/pull/616) ([maurolacy](https://github.com/maurolacy)) +- Move contracts to cw-tokens [\#613](https://github.com/CosmWasm/cw-plus/pull/613) ([ethanfrey](https://github.com/ethanfrey)) +- Add context to multitest execution errors [\#597](https://github.com/CosmWasm/cw-plus/pull/597) ([uint](https://github.com/uint)) ## [v0.11.1](https://github.com/CosmWasm/cw-plus/tree/v0.11.1) (2021-12-28) From 19c0bfa5cd2ba327f3396ffcf4d128938fb677ea Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 13:14:03 +0100 Subject: [PATCH 212/631] Add MIGRATING entry for upcoming 0.12.0 Type safe bounds migration. --- MIGRATING.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/MIGRATING.md b/MIGRATING.md index ea5b67c8d..11c6e9639 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -2,6 +2,50 @@ This guide lists API changes between *cw-plus* major releases. +## v0.11.0 -> v0.12.0 + +### Breaking Issues / PRs + +- Type safe `Bound`s [\#462](https://github.com/CosmWasm/cw-plus/issues/462) + +Bounds are now type-safe. That means the bound type must match the key / sub-key you are ranging over. + +Migration code example: + +```diff +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) +``` +Here the `ALLOW_LIST` key is of type `&Addr`. That's why we use `as_ref()` before the `map()` that builds the bound. +Notice also that this "forces" you to use `addr_validate()`, in order to build a bound over the proper type. + +You can still use untyped bounds, with the `ExclusiveRaw` and `InclusiveRaw` enum types. +Migration code example, in case you want to keep your raw bounds: + +```diff +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(|s| Bound::ExclusiveRaw(s.into())); + + let allowances = ALLOWANCES + .range(deps.storage, start, None, Order::Ascending) +``` +Notice that here we build a bound for an address, and using a raw bound allows us to skip address validation / build up. + ## v0.10.3 -> v0.11.0 ### Breaking Issues / PRs From fae49eb8bae461fa4ad832f0ba2c15356c062d8d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 21:16:42 +0100 Subject: [PATCH 213/631] Fix migration code context --- MIGRATING.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/MIGRATING.md b/MIGRATING.md index 11c6e9639..7dd66e185 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -14,8 +14,10 @@ Migration code example: ```diff fn list_allowed( - limit: Option, - ) -> StdResult { + deps: Deps, + start_after: Option, + 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())), @@ -35,7 +37,11 @@ Migration code example, in case you want to keep your raw bounds: ```diff pub fn query_all_allowances( - ) -> StdResult { + deps: Deps, + env: Env, + start_after: Option, + limit: Option, +) -> StdResult { let limit = calc_limit(limit); // we use raw addresses here.... - let start = start_after.map(Bound::exclusive); From 214fdc47b1cd89ca1b639d3b458dae86712a14c5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 22:02:55 +0100 Subject: [PATCH 214/631] Update storage-plus README.md --- packages/storage-plus/README.md | 43 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 214228bd5..edb17d8ed 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -314,7 +314,7 @@ fn demo() -> StdResult<()> { In addition to getting one particular item out of a map, we can iterate over the map (or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice `Bound`s helpers to easily allow pagination or custom ranges. +and we provide some nice [`Bound`](#Bound) helpers to easily allow pagination or custom ranges. The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. @@ -322,21 +322,28 @@ If `map.key()` took `&[u8]`, `map.prefix()` takes `()`). Once we have a prefix s over all items with `range(store, min, max, order)`. It supports `Order::Ascending` or `Order::Descending`. `min` is the lower bound and `max` is the higher bound. +If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to +limit the results to `n` items and start doing pagination. You can also set the `min` bound to +eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with +`take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any +perfect matches. + +### Bound + +`Bound` is a helper to build type-safe bounds on the keys or sub-keys you want to iterate over. +It also supports a raw (`Vec`) bounds specification, for the cases you don't want or can't use typed bounds. + ```rust -#[derive(Copy, Clone, Debug)] -pub enum Bound { - Inclusive(Vec), - Exclusive(Vec), - None, +#[derive(Clone, Debug)] +pub enum Bound<'a, K: PrimaryKey<'a>> { + Inclusive((K, PhantomData<&'a bool>)), + Exclusive((K, PhantomData<&'a bool>)), + InclusiveRaw(Vec), + ExclusiveRaw(Vec), } ``` -If the `min` and `max` bounds, it will return all items under this prefix. You can use `.take(n)` to -limit the results to `n` items and start doing pagination. You can also set the `min` bound to -eg. `Bound::Exclusive(last_value)` to start iterating over all items *after* the last value. Combined with -`take`, we easily have pagination support. You can also use `Bound::Inclusive(x)` when you want to include any -perfect matches. To better understand the API, please read the following example: - +To better understand the API, please read the following example: ```rust #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -358,7 +365,7 @@ fn demo() -> StdResult<()> { // iterate over them all let all: StdResult> = PEOPLE - .range(&store, Bound::None, Bound::None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); assert_eq!( all?, @@ -369,8 +376,8 @@ fn demo() -> StdResult<()> { let all: StdResult> = PEOPLE .range( &store, - Bound::Exclusive("jim"), - Bound::None, + Some(Bound::exclusive("jim")), + None, Order::Ascending, ) .collect(); @@ -384,7 +391,7 @@ fn demo() -> StdResult<()> { // get all under one key let all: StdResult> = ALLOWANCE .prefix("owner") - .range(&store, Bound::None, Bound::None, Order::Ascending) + .range(&store, None, None, Order::Ascending) .collect(); assert_eq!( all?, @@ -396,8 +403,8 @@ fn demo() -> StdResult<()> { .prefix("owner") .range( &store, - Bound::Exclusive("spender1"), - Bound::Inclusive("spender2"), + Some(Bound::exclusive("spender1")), + Some(Bound::inclusive("spender2")), Order::Descending, ) .collect(); From 291cc41495e875e97651030374a3bbfa8c51e5d0 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 31 Jan 2022 22:05:40 +0100 Subject: [PATCH 215/631] Add link to storage-plus README --- MIGRATING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MIGRATING.md b/MIGRATING.md index 7dd66e185..8fe761275 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -52,6 +52,8 @@ pub fn query_all_allowances( ``` Notice that here we build a bound for an address, and using a raw bound allows us to skip address validation / build up. +See storage-plus [README.md](./packages/storage-plus/README.md#Bound) for more information on `Bound`. + ## v0.10.3 -> v0.11.0 ### Breaking Issues / PRs From 652411cd8dfa14a90b720bfc07fb8f8ee597562f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 2 Feb 2022 20:41:02 +0100 Subject: [PATCH 216/631] Use ContractInfoResponse from cosmwasm_std --- packages/multi-test/src/wasm.rs | 38 ++++++--------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 49646d876..9a30d47e7 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -4,9 +4,9 @@ use std::ops::Deref; use cosmwasm_std::{ to_binary, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, - ContractResult, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, Order, Querier, - QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgExecutionResponse, - TransactionInfo, WasmMsg, WasmQuery, + ContractInfoResponse, ContractResult, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, + Order, Querier, QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, + SubMsgExecutionResponse, TransactionInfo, WasmMsg, WasmQuery, }; use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; use prost::Message; @@ -25,20 +25,6 @@ use cosmwasm_std::testing::mock_wasmd_attr; use anyhow::{bail, Context, Result as AnyResult}; -// TODO: we should import this from cosmwasm-std, but cannot due to non_exhaustive so copy here -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct ContractInfoResponse { - pub code_id: u64, - /// address that instantiated this contract - pub creator: String, - /// admin who can run migrations (if any) - pub admin: Option, - /// if set, the contract is pinned to the cache, and thus uses less gas when called - pub pinned: bool, - /// set if this contract has bound an IBC port - pub ibc_port: Option, -} - // Contract state is kept in Storage, separate from the contracts themselves const CONTRACTS: Map<&Addr, ContractData> = Map::new("contracts"); @@ -152,13 +138,8 @@ where WasmQuery::ContractInfo { contract_addr } => { let addr = api.addr_validate(&contract_addr)?; let contract = self.load_contract(storage, &addr)?; - let res = ContractInfoResponse { - code_id: contract.code_id as u64, - creator: contract.creator.to_string(), - admin: contract.admin.map(|x| x.to_string()), - pinned: false, - ibc_port: None, - }; + let mut res = ContractInfoResponse::new(contract.code_id as u64, contract.creator); + res.admin = contract.admin.map(|x| x.into()); to_binary(&res).map_err(Into::into) } query => bail!(Error::UnsupportedWasmQuery(query)), @@ -1063,13 +1044,8 @@ mod test { .query(&api, &wasm_storage, &querier, &block, query) .unwrap(); - let expected = ContractInfoResponse { - code_id: code_id as u64, - creator: "foobar".to_owned(), - admin: Some("admin".to_owned()), - pinned: false, - ibc_port: None, - }; + let mut expected = ContractInfoResponse::new(code_id as u64, "foobar"); + expected.admin = Some("admin".to_owned()); assert_eq!(expected, from_slice(&info).unwrap()); } From f285c674e55c552138556fe3254d5d5162bc0934 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 31 Jan 2022 11:28:51 +0100 Subject: [PATCH 217/631] Use ADMIN to control ics20 access, allow updates --- Cargo.lock | 1 + contracts/cw20-ics20/Cargo.toml | 1 + contracts/cw20-ics20/src/contract.rs | 23 +++++++++++++++-------- contracts/cw20-ics20/src/error.rs | 4 ++++ contracts/cw20-ics20/src/msg.rs | 6 +++++- contracts/cw20-ics20/src/state.rs | 7 +++++-- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56eb22914..1c7e38bc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -548,6 +548,7 @@ version = "0.12.0-alpha2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-controllers", "cw-storage-plus", "cw-utils", "cw2", diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index fe31dd250..ca7a1bc00 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -23,6 +23,7 @@ cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 82133c6a7..3182a3e62 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure_eq, from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, - MessageInfo, Order, PortIdResponse, Response, StdResult, + from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, Order, + PortIdResponse, Response, StdResult, }; use cw2::{get_contract_version, set_contract_version}; @@ -16,7 +16,7 @@ use crate::msg::{ AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, }; -use crate::state::{AllowInfo, Config, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; +use crate::state::{AllowInfo, Config, ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; use cw_utils::{maybe_addr, nonpayable, one_coin}; // version info for migration info @@ -25,7 +25,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, + mut deps: DepsMut, _env: Env, _info: MessageInfo, msg: InitMsg, @@ -33,10 +33,12 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { default_timeout: msg.default_timeout, - gov_contract: deps.api.addr_validate(&msg.gov_contract)?, }; CONFIG.save(deps.storage, &cfg)?; + let admin = deps.api.addr_validate(&msg.gov_contract)?; + ADMIN.set(deps.branch(), Some(admin))?; + // add all allows for allowed in msg.allowlist { let contract = deps.api.addr_validate(&allowed.contract)?; @@ -62,6 +64,10 @@ pub fn execute( execute_transfer(deps, env, msg, Amount::Native(coin), info.sender) } ExecuteMsg::Allow(allow) => execute_allow(deps, env, info, allow), + ExecuteMsg::UpdateAdmin { admin } => { + let admin = deps.api.addr_validate(&admin)?; + Ok(ADMIN.execute_update_admin(deps, info, Some(admin))?) + } } } @@ -151,8 +157,7 @@ pub fn execute_allow( info: MessageInfo, allow: AllowMsg, ) -> Result { - let cfg = CONFIG.load(deps.storage)?; - ensure_eq!(info.sender, cfg.gov_contract, ContractError::Unauthorized); + ADMIN.assert_admin(deps.as_ref(), &info.sender)?; let contract = deps.api.addr_validate(&allow.contract)?; let set = AllowInfo { @@ -207,6 +212,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ListAllowed { start_after, limit } => { to_binary(&list_allowed(deps, start_after, limit)?) } + QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), } } @@ -251,9 +257,10 @@ pub fn query_channel(deps: Deps, id: String) -> StdResult { fn query_config(deps: Deps) -> StdResult { let cfg = CONFIG.load(deps.storage)?; + let admin = ADMIN.get(deps)?.unwrap_or_else(|| Addr::unchecked("")); let res = ConfigResponse { default_timeout: cfg.default_timeout, - gov_contract: cfg.gov_contract.into(), + gov_contract: admin.into(), }; Ok(res) } diff --git a/contracts/cw20-ics20/src/error.rs b/contracts/cw20-ics20/src/error.rs index cdd3b0574..c9a6966a6 100644 --- a/contracts/cw20-ics20/src/error.rs +++ b/contracts/cw20-ics20/src/error.rs @@ -3,6 +3,7 @@ use std::string::FromUtf8Error; use thiserror::Error; use cosmwasm_std::StdError; +use cw_controllers::AdminError; use cw_utils::PaymentError; /// Never is a placeholder to ensure we don't return any errors @@ -17,6 +18,9 @@ pub enum ContractError { #[error("{0}")] Payment(#[from] PaymentError), + #[error("{0}")] + Admin(#[from] AdminError), + #[error("Channel doesn't exist: {id}")] NoSuchChannel { id: String }, diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index 044cbf2f6..c5330dd97 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -34,6 +34,8 @@ pub enum ExecuteMsg { Transfer(TransferMsg), /// This must be called by gov_contract, will allow a new cw20 token to be sent Allow(AllowMsg), + /// Change the admin (must be called by current admin) + UpdateAdmin { admin: String }, } /// This is the message we accept via Receive @@ -59,8 +61,10 @@ pub enum QueryMsg { /// Returns the details of the name channel, error if not created. /// Return type: ChannelResponse. Channel { id: String }, - /// Show the Config. Returns ConfigResponse + /// Show the Config. Returns ConfigResponse (currently including admin as well) Config {}, + /// Return AdminResponse + Admin {}, /// Query if a given cw20 contract is allowed. Returns AllowedResponse Allowed { contract: String }, /// List all allowed cw20 contracts. Returns ListAllowedResponse diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 79c127d8c..20277035a 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -1,10 +1,14 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::ContractError; use cosmwasm_std::{Addr, IbcEndpoint, StdResult, Storage, Uint128}; +use cw_controllers::Admin; use cw_storage_plus::{Item, Map}; +use crate::ContractError; + +pub const ADMIN: Admin = Admin::new("admin"); + pub const CONFIG: Item = Item::new("ics20_config"); // Used to pass info from the ibc_packet_receive to the reply handler @@ -28,7 +32,6 @@ pub struct ChannelState { #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { pub default_timeout: u64, - pub gov_contract: Addr, } #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] From 783f0d5fecf6ef0c810812b0be28a46f5b248c77 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 31 Jan 2022 13:36:58 +0100 Subject: [PATCH 218/631] Prepare better migrate function --- Cargo.lock | 1 + contracts/cw20-ics20/Cargo.toml | 1 + contracts/cw20-ics20/src/contract.rs | 34 ++++++++++++++++++++++++---- contracts/cw20-ics20/src/error.rs | 3 +++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c7e38bc2..e2ee01f14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -554,6 +554,7 @@ dependencies = [ "cw2", "cw20", "schemars", + "semver", "serde", "thiserror", ] diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index ca7a1bc00..765cc7035 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -25,6 +25,7 @@ cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } schemars = "0.8.1" +semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 3182a3e62..dbb52f015 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -2,8 +2,9 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, Order, - PortIdResponse, Response, StdResult, + PortIdResponse, Response, StdError, StdResult, }; +use semver::Version; use cw2::{get_contract_version, set_contract_version}; use cw20::{Cw20Coin, Cw20ReceiveMsg}; @@ -192,13 +193,36 @@ pub fn execute_allow( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let version = get_contract_version(deps.storage)?; - if version.contract != CONTRACT_NAME { + let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; + let stored = get_contract_version(deps.storage)?; + let storage_version: Version = stored.version.parse().map_err(from_semver)?; + + if CONTRACT_NAME != stored.contract { return Err(ContractError::CannotMigrate { - previous_contract: version.contract, + previous_contract: stored.contract, }); } - Ok(Response::default()) + if storage_version > version { + return Err(ContractError::CannotMigrateVersion { + previous_version: stored.version, + }); + } + + // for 0.12.0-alpha1 or earlier, migrate from the config.gov_contract to ADMIN + if storage_version <= "0.12.0-alpha1".parse().map_err(from_semver)? { + // DO migration + } + + if storage_version < version { + // we don't need to save anything if migrating from the same version + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + } + + Ok(Response::new()) +} + +fn from_semver(err: semver::Error) -> StdError { + StdError::generic_err(format!("Semver: {}", err)) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/cw20-ics20/src/error.rs b/contracts/cw20-ics20/src/error.rs index c9a6966a6..286ba4a62 100644 --- a/contracts/cw20-ics20/src/error.rs +++ b/contracts/cw20-ics20/src/error.rs @@ -51,6 +51,9 @@ pub enum ContractError { #[error("Cannot migrate from different contract type: {previous_contract}")] CannotMigrate { previous_contract: String }, + #[error("Cannot migrate from unsupported version: {previous_version}")] + CannotMigrateVersion { previous_version: String }, + #[error("Got a submessage reply with unknown id: {id}")] UnknownReplyId { id: u64 }, From 8d5524f8e40f650929c820f9771ffe64b7157f2f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 31 Jan 2022 13:45:08 +0100 Subject: [PATCH 219/631] Perform proper migration logic --- contracts/cw20-ics20/src/contract.rs | 21 +++++++++++++++++++-- contracts/cw20-ics20/src/lib.rs | 1 + contracts/cw20-ics20/src/migrations.rs | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 contracts/cw20-ics20/src/migrations.rs diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index dbb52f015..cbcd8767b 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -192,26 +192,43 @@ pub fn execute_allow( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { +pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; let stored = get_contract_version(deps.storage)?; let storage_version: Version = stored.version.parse().map_err(from_semver)?; + // First, ensure we are working from an equal or older version of this contract + // wrong type if CONTRACT_NAME != stored.contract { return Err(ContractError::CannotMigrate { previous_contract: stored.contract, }); } + // existing one is newer if storage_version > version { return Err(ContractError::CannotMigrateVersion { previous_version: stored.version, }); } + // Then, run the proper migration + // unsupported old version + if storage_version < "0.11.1".parse().map_err(from_semver)? { + return Err(ContractError::CannotMigrateVersion { + previous_version: stored.version, + }); + } // for 0.12.0-alpha1 or earlier, migrate from the config.gov_contract to ADMIN if storage_version <= "0.12.0-alpha1".parse().map_err(from_semver)? { - // DO migration + // Do v1 migration + let old_config = crate::migrations::v1::CONFIG.load(deps.storage)?; + ADMIN.set(deps.branch(), Some(old_config.gov_contract))?; + let config = Config { + default_timeout: old_config.default_timeout, + }; + CONFIG.save(deps.storage, &config)?; } + // otherwise no migration (yet) if storage_version < version { // we don't need to save anything if migrating from the same version diff --git a/contracts/cw20-ics20/src/lib.rs b/contracts/cw20-ics20/src/lib.rs index 5e579aafa..b9ceef245 100644 --- a/contracts/cw20-ics20/src/lib.rs +++ b/contracts/cw20-ics20/src/lib.rs @@ -2,6 +2,7 @@ pub mod amount; pub mod contract; mod error; pub mod ibc; +mod migrations; pub mod msg; pub mod state; mod test_helpers; diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs new file mode 100644 index 000000000..888df9418 --- /dev/null +++ b/contracts/cw20-ics20/src/migrations.rs @@ -0,0 +1,16 @@ +// v1 format is anything older than 0.12.0 +pub mod v1 { + use schemars::JsonSchema; + use serde::{Deserialize, Serialize}; + + use cosmwasm_std::Addr; + use cw_storage_plus::Item; + + #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] + pub struct ConfigV1 { + pub default_timeout: u64, + pub gov_contract: Addr, + } + + pub const CONFIG: Item = Item::new("ics20_config"); +} From 20c21779b082794ef30333ade457c20fe62a8f04 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 2 Feb 2022 20:53:28 +0100 Subject: [PATCH 220/631] Cleanup from pr review --- contracts/cw20-ics20/src/contract.rs | 18 ++++++++++-------- contracts/cw20-ics20/src/migrations.rs | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index cbcd8767b..35f946fd4 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -13,6 +13,7 @@ use cw_storage_plus::Bound; use crate::amount::Amount; use crate::error::ContractError; use crate::ibc::Ics20Packet; +use crate::migrations::v1; use crate::msg::{ AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, @@ -191,6 +192,9 @@ pub fn execute_allow( Ok(res) } +const MIGRATE_MIN_VERSION: &str = "0.11.1"; +const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; + #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; @@ -212,26 +216,24 @@ pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Resultv2 converstion if we are v1 style + if storage_version <= MIGRATE_VERSION_2.parse().map_err(from_semver)? { + let old_config = v1::CONFIG.load(deps.storage)?; ADMIN.set(deps.branch(), Some(old_config.gov_contract))?; let config = Config { default_timeout: old_config.default_timeout, }; CONFIG.save(deps.storage, &config)?; } - // otherwise no migration (yet) + // otherwise no migration (yet) - add them here + // we don't need to save anything if migrating from the same version if storage_version < version { - // we don't need to save anything if migrating from the same version set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; } diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index 888df9418..e874569a0 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -7,10 +7,10 @@ pub mod v1 { use cw_storage_plus::Item; #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] - pub struct ConfigV1 { + pub struct Config { pub default_timeout: u64, pub gov_contract: Addr, } - pub const CONFIG: Item = Item::new("ics20_config"); + pub const CONFIG: Item = Item::new("ics20_config"); } From bb4bac178cf5e499b4f65f78ef8af0b4a335ccd8 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 4 Feb 2022 12:51:22 +0100 Subject: [PATCH 221/631] CW3: Add proposal_id field to VoteInfo structure --- contracts/cw3-fixed-multisig/src/contract.rs | 2 ++ contracts/cw3-flex-multisig/src/contract.rs | 4 ++++ packages/cw3/src/query.rs | 1 + 3 files changed, 7 insertions(+) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 5928bcf82..8c2f530c7 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -337,6 +337,7 @@ fn query_vote(deps: Deps, proposal_id: u64, voter: String) -> StdResult StdResult Date: Sun, 6 Feb 2022 13:42:33 -0800 Subject: [PATCH 222/631] fix contract url link --- contracts/cw20-base/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-base/README.md b/contracts/cw20-base/README.md index 328b26742..01db9e054 100644 --- a/contracts/cw20-base/README.md +++ b/contracts/cw20-base/README.md @@ -44,5 +44,5 @@ calls, but then use the underlying implementation for the standard cw20 messages you want to support. The same with `QueryMsg`. You *could* reuse `instantiate` as it, but it is likely you will want to change it. And it is rather simple. -Look at [`cw20-staking`](../cw20-staking/README.md) for an example of how to "inherit" +Look at [`cw20-staking`](https://github.com/CosmWasm/cw-tokens/tree/main/contracts/cw20-staking) for an example of how to "inherit" all this token functionality and combine it with custom logic. From d3cdead992203a5720ea107fdc9ad4e95dcd5409 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 15:19:46 +0100 Subject: [PATCH 223/631] controllers: support custom queries --- packages/controllers/src/admin.rs | 24 +++++++++++++++--------- packages/controllers/src/claim.rs | 8 ++++++-- packages/controllers/src/hooks.rs | 13 +++++++------ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/packages/controllers/src/admin.rs b/packages/controllers/src/admin.rs index 61e0edf94..49cef71cf 100644 --- a/packages/controllers/src/admin.rs +++ b/packages/controllers/src/admin.rs @@ -3,7 +3,9 @@ use serde::{Deserialize, Serialize}; use std::fmt; use thiserror::Error; -use cosmwasm_std::{attr, Addr, Deps, DepsMut, MessageInfo, Response, StdError, StdResult}; +use cosmwasm_std::{ + attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, +}; use cw_storage_plus::Item; // TODO: should the return values end up in utils, so eg. cw4 can import them as well as this module? @@ -32,17 +34,17 @@ impl<'a> Admin<'a> { Admin(Item::new(namespace)) } - pub fn set(&self, deps: DepsMut, admin: Option) -> StdResult<()> { + pub fn set(&self, deps: DepsMut, admin: Option) -> StdResult<()> { self.0.save(deps.storage, &admin) } - pub fn get(&self, deps: Deps) -> StdResult> { + pub fn get(&self, deps: Deps) -> StdResult> { self.0.load(deps.storage) } /// Returns Ok(true) if this is an admin, Ok(false) if not and an Error if /// we hit an error with Api or Storage usage - pub fn is_admin(&self, deps: Deps, caller: &Addr) -> StdResult { + pub fn is_admin(&self, deps: Deps, caller: &Addr) -> StdResult { match self.0.load(deps.storage)? { Some(owner) => Ok(caller == &owner), None => Ok(false), @@ -51,7 +53,11 @@ impl<'a> Admin<'a> { /// Like is_admin but returns AdminError::NotAdmin if not admin. /// Helper for a nice one-line auth check. - pub fn assert_admin(&self, deps: Deps, caller: &Addr) -> Result<(), AdminError> { + pub fn assert_admin( + &self, + deps: Deps, + caller: &Addr, + ) -> Result<(), AdminError> { if !self.is_admin(deps, caller)? { Err(AdminError::NotAdmin {}) } else { @@ -59,9 +65,9 @@ impl<'a> Admin<'a> { } } - pub fn execute_update_admin( + pub fn execute_update_admin( &self, - deps: DepsMut, + deps: DepsMut, info: MessageInfo, new_admin: Option, ) -> Result, AdminError> @@ -160,14 +166,14 @@ mod tests { let info = mock_info(imposter.as_ref(), &[]); let new_admin = Some(friend.clone()); let err = control - .execute_update_admin::(deps.as_mut(), info, new_admin.clone()) + .execute_update_admin::(deps.as_mut(), info, new_admin.clone()) .unwrap_err(); assert_eq!(AdminError::NotAdmin {}, err); // owner can update let info = mock_info(owner.as_ref(), &[]); let res = control - .execute_update_admin::(deps.as_mut(), info, new_admin) + .execute_update_admin::(deps.as_mut(), info, new_admin) .unwrap(); assert_eq!(0, res.messages.len()); diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index a6d6c3d25..60025fce3 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, BlockInfo, Deps, StdResult, Storage, Uint128}; +use cosmwasm_std::{Addr, BlockInfo, CustomQuery, Deps, StdResult, Storage, Uint128}; use cw_storage_plus::Map; use cw_utils::Expiration; @@ -86,7 +86,11 @@ impl<'a> Claims<'a> { Ok(to_send) } - pub fn query_claims(&self, deps: Deps, address: &Addr) -> StdResult { + pub fn query_claims( + &self, + deps: Deps, + address: &Addr, + ) -> StdResult { let claims = self.0.may_load(deps.storage, address)?.unwrap_or_default(); Ok(ClaimsResponse { claims }) } diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index c42af5b85..673b8c8de 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -4,7 +4,8 @@ use std::fmt; use thiserror::Error; use cosmwasm_std::{ - attr, Addr, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, Storage, SubMsg, + attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, Storage, + SubMsg, }; use cw_storage_plus::Item; @@ -73,10 +74,10 @@ impl<'a> Hooks<'a> { .collect() } - pub fn execute_add_hook( + pub fn execute_add_hook( &self, admin: &Admin, - deps: DepsMut, + deps: DepsMut, info: MessageInfo, addr: Addr, ) -> Result, HookError> @@ -94,10 +95,10 @@ impl<'a> Hooks<'a> { Ok(Response::new().add_attributes(attributes)) } - pub fn execute_remove_hook( + pub fn execute_remove_hook( &self, admin: &Admin, - deps: DepsMut, + deps: DepsMut, info: MessageInfo, addr: Addr, ) -> Result, HookError> @@ -115,7 +116,7 @@ impl<'a> Hooks<'a> { Ok(Response::new().add_attributes(attributes)) } - pub fn query_hooks(&self, deps: Deps) -> StdResult { + pub fn query_hooks(&self, deps: Deps) -> StdResult { let hooks = self.0.may_load(deps.storage)?.unwrap_or_default(); let hooks = hooks.into_iter().map(String::from).collect(); Ok(HooksResponse { hooks }) From f014234c257604147dd24bf685ab53d8a03874d6 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 22:23:50 +0100 Subject: [PATCH 224/631] cw20: support custom queries --- packages/cw20/src/helpers.rs | 52 +++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index 82bcafc4a..f1e3df19b 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, Empty, Querier, QuerierWrapper, StdResult, Uint128, WasmMsg, + to_binary, Addr, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, Uint128, WasmMsg, WasmQuery, }; @@ -34,11 +34,12 @@ impl Cw20Contract { } /// Get token balance for the given address - pub fn balance>( - &self, - querier: &Q, - address: T, - ) -> StdResult { + pub fn balance(&self, querier: &Q, address: T) -> StdResult + where + Q: Querier, + T: Into, + CQ: CustomQuery, + { let msg = Cw20QueryMsg::Balance { address: address.into(), }; @@ -47,29 +48,39 @@ impl Cw20Contract { msg: to_binary(&msg)?, } .into(); - let res: BalanceResponse = QuerierWrapper::::new(querier).query(&query)?; + let res: BalanceResponse = QuerierWrapper::::new(querier).query(&query)?; Ok(res.balance) } /// Get metadata from the contract. This is a good check that the address /// is a valid Cw20 contract. - pub fn meta(&self, querier: &Q) -> StdResult { + pub fn meta(&self, querier: &Q) -> StdResult + where + Q: Querier, + CQ: CustomQuery, + { let msg = Cw20QueryMsg::TokenInfo {}; let query = WasmQuery::Smart { contract_addr: self.addr().into(), msg: to_binary(&msg)?, } .into(); - QuerierWrapper::::new(querier).query(&query) + QuerierWrapper::::new(querier).query(&query) } /// Get allowance of spender to use owner's account - pub fn allowance, U: Into>( + pub fn allowance( &self, querier: &Q, owner: T, spender: U, - ) -> StdResult { + ) -> StdResult + where + Q: Querier, + T: Into, + U: Into, + CQ: CustomQuery, + { let msg = Cw20QueryMsg::Allowance { owner: owner.into(), spender: spender.into(), @@ -79,27 +90,32 @@ impl Cw20Contract { msg: to_binary(&msg)?, } .into(); - QuerierWrapper::::new(querier).query(&query) + QuerierWrapper::::new(querier).query(&query) } /// Find info on who can mint, and how much - pub fn minter(&self, querier: &Q) -> StdResult> { + pub fn minter(&self, querier: &Q) -> StdResult> + where + Q: Querier, + CQ: CustomQuery, + { let msg = Cw20QueryMsg::Minter {}; let query = WasmQuery::Smart { contract_addr: self.addr().into(), msg: to_binary(&msg)?, } .into(); - QuerierWrapper::::new(querier).query(&query) + QuerierWrapper::::new(querier).query(&query) } /// returns true if the contract supports the allowance extension - pub fn has_allowance(&self, querier: &Q) -> bool { - self.allowance(querier, self.addr(), self.addr()).is_ok() + pub fn has_allowance(&self, querier: &Q) -> bool { + self.allowance::<_, _, _, CQ>(querier, self.addr(), self.addr()) + .is_ok() } /// returns true if the contract supports the mintable extension - pub fn is_mintable(&self, querier: &Q) -> bool { - self.minter(querier).is_ok() + pub fn is_mintable(&self, querier: &Q) -> bool { + self.minter::<_, CQ>(querier).is_ok() } } From 6be3f6ee89f9047a2e2c645dcad111d4b2ee1d61 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 22:23:58 +0100 Subject: [PATCH 225/631] cw4: support custom queries --- packages/cw4/src/helpers.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/cw4/src/helpers.rs b/packages/cw4/src/helpers.rs index c692f29e7..0761e5c39 100644 --- a/packages/cw4/src/helpers.rs +++ b/packages/cw4/src/helpers.rs @@ -2,7 +2,8 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, Empty, QuerierWrapper, QueryRequest, StdResult, WasmMsg, WasmQuery, + to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, WasmMsg, + WasmQuery, }; use crate::msg::Cw4ExecuteMsg; @@ -54,7 +55,7 @@ impl Cw4Contract { self.encode_msg(msg) } - fn encode_smart_query(&self, msg: Cw4QueryMsg) -> StdResult> { + fn encode_smart_query(&self, msg: Cw4QueryMsg) -> StdResult> { Ok(WasmQuery::Smart { contract_addr: self.addr().into(), msg: to_binary(&msg)?, @@ -63,7 +64,7 @@ impl Cw4Contract { } /// Show the hooks - pub fn hooks(&self, querier: &QuerierWrapper) -> StdResult> { + pub fn hooks(&self, querier: &QuerierWrapper) -> StdResult> { let query = self.encode_smart_query(Cw4QueryMsg::Hooks {})?; let res: HooksResponse = querier.query(&query)?; Ok(res.hooks) From 3edbdc75dfa3c3f72c2273a7488881d1362ac626 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 22:25:35 +0100 Subject: [PATCH 226/631] multi-test: support custom queries --- packages/multi-test/src/app.rs | 2 +- packages/multi-test/src/contracts.rs | 130 ++++++++++++++------------- packages/multi-test/src/wasm.rs | 8 +- 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index c23e6873a..f06ba6ac4 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -557,7 +557,7 @@ where { /// This registers contract code (like uploading wasm bytecode on a chain), /// so it can later be used to instantiate a contract. - pub fn store_code(&mut self, code: Box>) -> u64 { + pub fn store_code(&mut self, code: Box>) -> u64 { self.init_modules(|router, _, _| router.wasm.store_code(code) as u64) } diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index e703b75a8..72bf76950 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -4,19 +4,21 @@ use std::error::Error; use std::fmt::{self, Debug, Display}; use cosmwasm_std::{ - from_slice, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Reply, Response, SubMsg, + from_slice, Binary, CosmosMsg, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, Reply, + Response, SubMsg, }; use anyhow::{anyhow, bail, Context, Result as AnyResult}; /// Interface to call into a Contract -pub trait Contract +pub trait Contract where T: Clone + fmt::Debug + PartialEq + JsonSchema, + Q: CustomQuery, { fn execute( &self, - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: Vec, @@ -24,31 +26,32 @@ where fn instantiate( &self, - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: Vec, ) -> AnyResult>; - fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult; + fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult; - fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; + fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; - fn reply(&self, deps: DepsMut, env: Env, msg: Reply) -> AnyResult>; + fn reply(&self, deps: DepsMut, env: Env, msg: Reply) -> AnyResult>; - fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; + fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; } -type ContractFn = - fn(deps: DepsMut, env: Env, info: MessageInfo, msg: T) -> Result, E>; -type PermissionedFn = fn(deps: DepsMut, env: Env, msg: T) -> Result, E>; -type ReplyFn = fn(deps: DepsMut, env: Env, msg: Reply) -> Result, E>; -type QueryFn = fn(deps: Deps, env: Env, msg: T) -> Result; +type ContractFn = + fn(deps: DepsMut, env: Env, info: MessageInfo, msg: T) -> Result, E>; +type PermissionedFn = fn(deps: DepsMut, env: Env, msg: T) -> Result, E>; +type ReplyFn = fn(deps: DepsMut, env: Env, msg: Reply) -> Result, E>; +type QueryFn = fn(deps: Deps, env: Env, msg: T) -> Result; -type ContractClosure = Box Result, E>>; -type PermissionedClosure = Box Result, E>>; -type ReplyClosure = Box Result, E>>; -type QueryClosure = Box Result>; +type ContractClosure = + Box, Env, MessageInfo, T) -> Result, E>>; +type PermissionedClosure = Box, Env, T) -> Result, E>>; +type ReplyClosure = Box, Env, Reply) -> Result, E>>; +type QueryClosure = Box, Env, T) -> Result>; /// Wraps the exported functions from a contract and provides the normalized format /// Place T4 and E4 at the end, as we just want default placeholders for most contracts that don't have sudo @@ -60,6 +63,7 @@ pub struct ContractWrapper< E2, E3, C = Empty, + Q = Empty, T4 = Empty, E4 = anyhow::Error, E5 = anyhow::Error, @@ -78,16 +82,17 @@ pub struct ContractWrapper< E5: Display + Debug + Send + Sync + 'static, E6: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema, + Q: CustomQuery + DeserializeOwned + 'static, { - execute_fn: ContractClosure, - instantiate_fn: ContractClosure, - query_fn: QueryClosure, - sudo_fn: Option>, - reply_fn: Option>, - migrate_fn: Option>, + execute_fn: ContractClosure, + instantiate_fn: ContractClosure, + query_fn: QueryClosure, + sudo_fn: Option>, + reply_fn: Option>, + migrate_fn: Option>, } -impl ContractWrapper +impl ContractWrapper where T1: DeserializeOwned + Debug + 'static, T2: DeserializeOwned + 'static, @@ -96,13 +101,14 @@ where E2: Display + Debug + Send + Sync + 'static, E3: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + Q: CustomQuery + DeserializeOwned + 'static, { pub fn new( - execute_fn: ContractFn, - instantiate_fn: ContractFn, - query_fn: QueryFn, + execute_fn: ContractFn, + instantiate_fn: ContractFn, + query_fn: QueryFn, ) -> Self { - ContractWrapper { + Self { execute_fn: Box::new(execute_fn), instantiate_fn: Box::new(instantiate_fn), query_fn: Box::new(query_fn), @@ -115,11 +121,11 @@ where /// this will take a contract that returns Response and will "upgrade" it /// to Response if needed to be compatible with a chain-specific extension pub fn new_with_empty( - execute_fn: ContractFn, - instantiate_fn: ContractFn, - query_fn: QueryFn, + execute_fn: ContractFn, + instantiate_fn: ContractFn, + query_fn: QueryFn, ) -> Self { - ContractWrapper { + Self { execute_fn: customize_fn(execute_fn), instantiate_fn: customize_fn(instantiate_fn), query_fn: Box::new(query_fn), @@ -130,8 +136,8 @@ where } } -impl - ContractWrapper +impl + ContractWrapper where T1: DeserializeOwned + Debug + 'static, T2: DeserializeOwned + 'static, @@ -145,11 +151,12 @@ where E5: Display + Debug + Send + Sync + 'static, E6: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + Q: CustomQuery + DeserializeOwned + 'static, { pub fn with_sudo( self, - sudo_fn: PermissionedFn, - ) -> ContractWrapper + sudo_fn: PermissionedFn, + ) -> ContractWrapper where T4A: DeserializeOwned + 'static, E4A: Display + Debug + Send + Sync + 'static, @@ -166,8 +173,8 @@ where pub fn with_sudo_empty( self, - sudo_fn: PermissionedFn, - ) -> ContractWrapper + sudo_fn: PermissionedFn, + ) -> ContractWrapper where T4A: DeserializeOwned + 'static, E4A: Display + Debug + Send + Sync + 'static, @@ -184,8 +191,8 @@ where pub fn with_reply( self, - reply_fn: ReplyFn, - ) -> ContractWrapper + reply_fn: ReplyFn, + ) -> ContractWrapper where E5A: Display + Debug + Send + Sync + 'static, { @@ -202,8 +209,8 @@ where /// A correlate of new_with_empty pub fn with_reply_empty( self, - reply_fn: ReplyFn, - ) -> ContractWrapper + reply_fn: ReplyFn, + ) -> ContractWrapper where E5A: Display + Debug + Send + Sync + 'static, { @@ -219,8 +226,8 @@ where pub fn with_migrate( self, - migrate_fn: PermissionedFn, - ) -> ContractWrapper + migrate_fn: PermissionedFn, + ) -> ContractWrapper where T6A: DeserializeOwned + 'static, E6A: Display + Debug + Send + Sync + 'static, @@ -237,8 +244,8 @@ where pub fn with_migrate_empty( self, - migrate_fn: PermissionedFn, - ) -> ContractWrapper + migrate_fn: PermissionedFn, + ) -> ContractWrapper where T6A: DeserializeOwned + 'static, E6A: Display + Debug + Send + Sync + 'static, @@ -254,28 +261,30 @@ where } } -fn customize_fn(raw_fn: ContractFn) -> ContractClosure +fn customize_fn(raw_fn: ContractFn) -> ContractClosure where T: DeserializeOwned + 'static, E: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + Q: CustomQuery + DeserializeOwned + 'static, { let customized = - move |deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { + move |deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { raw_fn(deps, env, info, msg).map(customize_response::) }; Box::new(customized) } -fn customize_permissioned_fn( - raw_fn: PermissionedFn, -) -> PermissionedClosure +fn customize_permissioned_fn( + raw_fn: PermissionedFn, +) -> PermissionedClosure where T: DeserializeOwned + 'static, E: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + Q: CustomQuery + DeserializeOwned + 'static, { - let customized = move |deps: DepsMut, env: Env, msg: T| -> Result, E> { + let customized = move |deps: DepsMut, env: Env, msg: T| -> Result, E> { raw_fn(deps, env, msg).map(customize_response::) }; Box::new(customized) @@ -315,8 +324,8 @@ where } } -impl Contract - for ContractWrapper +impl Contract + for ContractWrapper where T1: DeserializeOwned + Debug + Clone, T2: DeserializeOwned + Debug + Clone, @@ -330,10 +339,11 @@ where E5: Display + Debug + Send + Sync + 'static, E6: Display + Debug + Send + Sync + 'static, C: Clone + fmt::Debug + PartialEq + JsonSchema, + Q: CustomQuery + DeserializeOwned, { fn execute( &self, - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: Vec, @@ -349,7 +359,7 @@ where fn instantiate( &self, - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: Vec, @@ -363,7 +373,7 @@ where )) } - fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult { + fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult { let msg: T3 = from_slice(&msg)?; (self.query_fn)(deps, env, msg.clone()) .map_err(anyhow::Error::from) @@ -374,7 +384,7 @@ where } // this returns an error if the contract doesn't implement sudo - fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { + fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { let msg = from_slice(&msg)?; match &self.sudo_fn { Some(sudo) => sudo(deps, env, msg).map_err(|err| anyhow!(err)), @@ -383,7 +393,7 @@ where } // this returns an error if the contract doesn't implement reply - fn reply(&self, deps: DepsMut, env: Env, reply_data: Reply) -> AnyResult> { + fn reply(&self, deps: DepsMut, env: Env, reply_data: Reply) -> AnyResult> { match &self.reply_fn { Some(reply) => reply(deps, env, reply_data).map_err(|err| anyhow!(err)), None => bail!("reply not implemented for contract"), @@ -391,7 +401,7 @@ where } // this returns an error if the contract doesn't implement migrate - fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { + fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { let msg = from_slice(&msg)?; match &self.migrate_fn { Some(migrate) => migrate(deps, env, msg).map_err(|err| anyhow!(err)), diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 9a30d47e7..ce793c3af 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -99,7 +99,7 @@ pub trait Wasm { pub struct WasmKeeper { /// code is in-memory lookup that stands in for wasm code /// this can only be edited on the WasmRouter, and just read in caches - codes: HashMap>>, + codes: HashMap>>, /// Just markers to make type elision fork when using it as `Wasm` trait _p: std::marker::PhantomData, } @@ -180,7 +180,7 @@ where } impl WasmKeeper { - pub fn store_code(&mut self, code: Box>) -> usize { + pub fn store_code(&mut self, code: Box>) -> usize { let idx = self.codes.len() + 1; self.codes.insert(idx, code); idx @@ -706,7 +706,7 @@ where action: F, ) -> AnyResult where - F: FnOnce(&Box>, Deps, Env) -> AnyResult, + F: FnOnce(&Box>, Deps, Env) -> AnyResult, { let contract = self.load_contract(storage, &address)?; let handler = self @@ -734,7 +734,7 @@ where action: F, ) -> AnyResult where - F: FnOnce(&Box>, DepsMut, Env) -> AnyResult, + F: FnOnce(&Box>, DepsMut, Env) -> AnyResult, ExecC: DeserializeOwned, { let contract = self.load_contract(storage, &address)?; From bc08740e9dffacf51ed2fb5b9ccb9c063e49b453 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 22:40:45 +0100 Subject: [PATCH 227/631] lints --- packages/multi-test/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index a2071a08e..0ee12f501 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -6,6 +6,8 @@ //! //! To understand the design of this module, please refer to `../DESIGN.md` +#![allow(clippy::type_complexity)] + mod app; mod bank; mod contracts; From 03a3d0cf96a14709e81d8dcd1a38ca89bdda833f Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Feb 2022 22:43:05 +0100 Subject: [PATCH 228/631] storage-plus: support custom queries --- packages/storage-plus/src/helpers.rs | 8 ++++---- packages/storage-plus/src/item.rs | 10 ++++++++-- packages/storage-plus/src/map.rs | 6 +++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/src/helpers.rs b/packages/storage-plus/src/helpers.rs index 6f566ea2e..701b014fe 100644 --- a/packages/storage-plus/src/helpers.rs +++ b/packages/storage-plus/src/helpers.rs @@ -10,7 +10,7 @@ use std::any::type_name; use crate::keys::Key; use cosmwasm_std::{ - from_slice, to_vec, Addr, Binary, ContractResult, Empty, QuerierWrapper, QueryRequest, + from_slice, to_vec, Addr, Binary, ContractResult, CustomQuery, QuerierWrapper, QueryRequest, StdError, StdResult, SystemResult, WasmQuery, }; @@ -93,12 +93,12 @@ pub(crate) fn encode_length(namespace: &[u8]) -> [u8; 2] { /// This is similar to querier.query(WasmQuery::Raw{}), except it does NOT parse the /// result, but return a possibly empty Binary to be handled by the calling code. /// That is essential to handle b"" as None. -pub(crate) fn query_raw( - querier: &QuerierWrapper, +pub(crate) fn query_raw( + querier: &QuerierWrapper, contract_addr: Addr, key: Binary, ) -> StdResult { - let request: QueryRequest = WasmQuery::Raw { + let request: QueryRequest = WasmQuery::Raw { contract_addr: contract_addr.into(), key, } diff --git a/packages/storage-plus/src/item.rs b/packages/storage-plus/src/item.rs index 93b202bbf..312a87fef 100644 --- a/packages/storage-plus/src/item.rs +++ b/packages/storage-plus/src/item.rs @@ -2,7 +2,9 @@ use serde::de::DeserializeOwned; use serde::Serialize; use std::marker::PhantomData; -use cosmwasm_std::{to_vec, Addr, QuerierWrapper, StdError, StdResult, Storage, WasmQuery}; +use cosmwasm_std::{ + to_vec, Addr, CustomQuery, QuerierWrapper, StdError, StdResult, Storage, WasmQuery, +}; use crate::helpers::{may_deserialize, must_deserialize}; @@ -77,7 +79,11 @@ where /// from a remote contract in a type-safe way using WasmQuery::RawQuery. /// /// Note that we expect an Item to be set, and error if there is no data there - pub fn query(&self, querier: &QuerierWrapper, remote_contract: Addr) -> StdResult { + pub fn query( + &self, + querier: &QuerierWrapper, + remote_contract: Addr, + ) -> StdResult { let request = WasmQuery::Raw { contract_addr: remote_contract.into(), key: self.storage_key.into(), diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 0b50944ab..398521f3a 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -15,7 +15,7 @@ use crate::keys::{Key, PrimaryKey}; use crate::path::Path; #[cfg(feature = "iterator")] use crate::prefix::{namespaced_prefix_range, Prefix}; -use cosmwasm_std::{from_slice, Addr, QuerierWrapper, StdError, StdResult, Storage}; +use cosmwasm_std::{from_slice, Addr, CustomQuery, QuerierWrapper, StdError, StdResult, Storage}; #[derive(Debug, Clone)] pub struct Map<'a, K, T> { @@ -95,9 +95,9 @@ where /// If you import the proper Map from the remote contract, this will let you read the data /// from a remote contract in a type-safe way using WasmQuery::RawQuery - pub fn query( + pub fn query( &self, - querier: &QuerierWrapper, + querier: &QuerierWrapper, remote_contract: Addr, k: K, ) -> StdResult> { From 13464aa289c688bb1710f8526dbc2ec3f4a29275 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 8 Feb 2022 21:15:20 +0100 Subject: [PATCH 229/631] Update balance in transfer, reduce on_packet_failure, like ibctransfer --- contracts/cw20-ics20/src/contract.rs | 13 +++++++++---- contracts/cw20-ics20/src/ibc.rs | 13 +++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 35f946fd4..706a16073 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -18,7 +18,10 @@ use crate::msg::{ AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, }; -use crate::state::{AllowInfo, Config, ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG}; +use crate::state::{ + increase_channel_balance, AllowInfo, Config, ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, + CONFIG, +}; use cw_utils::{maybe_addr, nonpayable, one_coin}; // version info for migration info @@ -130,6 +133,11 @@ pub fn execute_transfer( ); packet.validate()?; + // Update the balance now (optimistically) like ibctransfer modules. + // In on_packet_failure (ack with error message or a timeout), we reduce the balance appropriately. + // This means the channel works fine if success acks are not relayed. + increase_channel_balance(deps.storage, &msg.channel, &amount.denom(), amount.amount())?; + // prepare ibc message let msg = IbcMsg::SendPacket { channel_id: msg.channel, @@ -137,9 +145,6 @@ pub fn execute_transfer( timeout: timeout.into(), }; - // Note: we update local state when we get ack - do not count this transfer towards anything until acked - // similar event messages like ibctransfer module - // send response let res = Response::new() .add_message(msg) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index ebc3139cb..d1a4da259 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -11,8 +11,8 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ - increase_channel_balance, reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, - ReplyArgs, ALLOW_LIST, CHANNEL_INFO, REPLY_ARGS, + reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, + CHANNEL_INFO, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -312,8 +312,9 @@ pub fn ibc_packet_timeout( } // update the balance stored on this (channel, denom) index -fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result { +fn on_packet_success(_deps: DepsMut, packet: IbcPacket) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; + // similar event messages like ibctransfer module let attributes = vec![ attr("action", "acknowledge"), @@ -324,9 +325,6 @@ fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result Result { let msg: Ics20Packet = from_binary(&packet.data)?; + // undo the balance update + reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; + let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; let send = send_amount(to_send, msg.sender.clone()); From 3696e600716e131ca01cd14cabbf14bdc28ed3f6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 8 Feb 2022 21:26:26 +0100 Subject: [PATCH 230/631] Update tests --- contracts/cw20-ics20/src/ibc.rs | 45 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index d1a4da259..f7e6abb3f 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -386,9 +386,11 @@ mod test { use super::*; use crate::test_helpers::*; - use crate::contract::query_channel; - use cosmwasm_std::testing::mock_env; - use cosmwasm_std::{coins, to_vec, IbcAcknowledgement, IbcEndpoint, IbcTimeout, Timestamp}; + use crate::contract::{execute, query_channel}; + use crate::msg::{ExecuteMsg, TransferMsg}; + use cosmwasm_std::testing::{mock_env, mock_info}; + use cosmwasm_std::{coins, to_vec, IbcEndpoint, IbcTimeout, Timestamp}; + use cw20::Cw20ReceiveMsg; #[test] fn check_ack_json() { @@ -447,6 +449,7 @@ mod test { ) } + #[allow(dead_code)] fn mock_sent_packet(my_channel: &str, amount: u128, denom: &str, sender: &str) -> IbcPacket { let data = Ics20Packet { denom: denom.into(), @@ -468,6 +471,7 @@ mod test { IbcTimeout::with_timestamp(Timestamp::from_seconds(1665321069)), ) } + fn mock_receive_packet( my_channel: &str, amount: u128, @@ -509,23 +513,31 @@ mod test { ); // prepare some mock packets - let sent_packet = mock_sent_packet(send_channel, 987654321, cw20_denom, "local-sender"); let recv_packet = mock_receive_packet(send_channel, 876543210, cw20_denom, "local-rcpt"); let recv_high_packet = mock_receive_packet(send_channel, 1876543210, cw20_denom, "local-rcpt"); - let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); // cannot receive this denom yet + let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); - // we get a success cache (ack) for a send - let msg = IbcPacketAckMsg::new(IbcAcknowledgement::new(ack_success()), sent_packet); - let res = ibc_packet_ack(deps.as_mut(), mock_env(), msg).unwrap(); - assert_eq!(0, res.messages.len()); + // we send some cw20 tokens over + let transfer = TransferMsg { + channel: send_channel.to_string(), + remote_address: "remote-rcpt".to_string(), + timeout: None, + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "local-sender".to_string(), + amount: Uint128::new(987654321), + msg: to_binary(&transfer).unwrap(), + }); + let info = mock_info(cw20_addr, &[]); + execute(deps.as_mut(), mock_env(), info, msg).unwrap(); // query channel state|_| let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); @@ -566,7 +578,6 @@ mod test { let denom = "uatom"; // prepare some mock packets - let sent_packet = mock_sent_packet(send_channel, 987654321, denom, "local-sender"); let recv_packet = mock_receive_packet(send_channel, 876543210, denom, "local-rcpt"); let recv_high_packet = mock_receive_packet(send_channel, 1876543210, denom, "local-rcpt"); @@ -578,10 +589,14 @@ mod test { let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); - // we get a success cache (ack) for a send - let msg = IbcPacketAckMsg::new(IbcAcknowledgement::new(ack_success()), sent_packet); - let res = ibc_packet_ack(deps.as_mut(), mock_env(), msg).unwrap(); - assert_eq!(0, res.messages.len()); + // we transfer some tokens + let msg = ExecuteMsg::Transfer(TransferMsg { + channel: send_channel.to_string(), + remote_address: "my-remote-address".to_string(), + timeout: None, + }); + let info = mock_info("local-sender", &coins(987654321, denom)); + execute(deps.as_mut(), mock_env(), info, msg).unwrap(); // query channel state|_| let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); @@ -606,7 +621,7 @@ mod test { let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); matches!(ack, Ics20Ack::Result(_)); - // TODO: we must call the reply block + // only need to call reply block on error case // query channel state let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); From 82094c82274e399f47792042c64f37672e38ea2c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 8 Feb 2022 21:45:13 +0100 Subject: [PATCH 231/631] Check sent ibc packet in tests --- contracts/cw20-ics20/src/ibc.rs | 43 ++++++++++++++------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index f7e6abb3f..7538d84bd 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -389,7 +389,7 @@ mod test { use crate::contract::{execute, query_channel}; use crate::msg::{ExecuteMsg, TransferMsg}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{coins, to_vec, IbcEndpoint, IbcTimeout, Timestamp}; + use cosmwasm_std::{coins, to_vec, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; use cw20::Cw20ReceiveMsg; #[test] @@ -449,29 +449,6 @@ mod test { ) } - #[allow(dead_code)] - fn mock_sent_packet(my_channel: &str, amount: u128, denom: &str, sender: &str) -> IbcPacket { - let data = Ics20Packet { - denom: denom.into(), - amount: amount.into(), - sender: sender.to_string(), - receiver: "remote-rcpt".to_string(), - }; - IbcPacket::new( - to_binary(&data).unwrap(), - IbcEndpoint { - port_id: CONTRACT_PORT.to_string(), - channel_id: my_channel.to_string(), - }, - IbcEndpoint { - port_id: REMOTE_PORT.to_string(), - channel_id: "channel-1234".to_string(), - }, - 2, - IbcTimeout::with_timestamp(Timestamp::from_seconds(1665321069)), - ) - } - fn mock_receive_packet( my_channel: &str, amount: u128, @@ -537,7 +514,23 @@ mod test { msg: to_binary(&transfer).unwrap(), }); let info = mock_info(cw20_addr, &[]); - execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(1, res.messages.len()); + let expected = Ics20Packet { + denom: cw20_denom.into(), + amount: Uint128::new(987654321), + sender: "local-sender".to_string(), + receiver: "remote-rcpt".to_string(), + }; + let timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); + assert_eq!( + &res.messages[0], + &SubMsg::new(IbcMsg::SendPacket { + channel_id: send_channel.to_string(), + data: to_binary(&expected).unwrap(), + timeout: IbcTimeout::with_timestamp(timeout), + }) + ); // query channel state|_| let state = query_channel(deps.as_ref(), send_channel.to_string()).unwrap(); From 2ea606be2e9af33a4f23baf24506a798711cb2d7 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 9 Feb 2022 12:35:41 +0100 Subject: [PATCH 232/631] Add version on packet, so we can use old ack handling for in-flight packets --- contracts/cw20-ics20/src/ibc.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 7538d84bd..f666db322 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -11,8 +11,8 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ - reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, - CHANNEL_INFO, REPLY_ARGS, + increase_channel_balance, reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, + ReplyArgs, ALLOW_LIST, CHANNEL_INFO, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -32,8 +32,12 @@ pub struct Ics20Packet { pub receiver: String, /// the sender address pub sender: String, + /// used only by us to control ack handling + pub v: Option, } +const V2: u32 = 2; + impl Ics20Packet { pub fn new>(amount: Uint128, denom: T, sender: &str, receiver: &str) -> Self { Ics20Packet { @@ -41,6 +45,7 @@ impl Ics20Packet { amount, sender: sender.to_string(), receiver: receiver.to_string(), + v: Some(V2), } } @@ -312,9 +317,15 @@ pub fn ibc_packet_timeout( } // update the balance stored on this (channel, denom) index -fn on_packet_success(_deps: DepsMut, packet: IbcPacket) -> Result { +fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; + // if this was for an older (pre-v2) packet we send continue with old behavior + // (this is needed for transitioning on a system with pending packet) + if msg.v.is_none() { + increase_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; + } + // similar event messages like ibctransfer module let attributes = vec![ attr("action", "acknowledge"), @@ -336,8 +347,10 @@ fn on_packet_failure( ) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; - // undo the balance update - reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; + // undo the balance update (but not for pre-v2/None packets which didn't add before sending) + if msg.v.is_some() { + reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; + } let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; @@ -413,7 +426,7 @@ mod test { "wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc", ); // Example message generated from the SDK - let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n"}"#; + let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n","v":2}"#; let encdoded = String::from_utf8(to_vec(&packet).unwrap()).unwrap(); assert_eq!(expected, encdoded.as_str()); @@ -461,6 +474,7 @@ mod test { amount: amount.into(), sender: "remote-sender".to_string(), receiver: receiver.to_string(), + v: Some(V2), }; print!("Packet denom: {}", &data.denom); IbcPacket::new( @@ -521,6 +535,7 @@ mod test { amount: Uint128::new(987654321), sender: "local-sender".to_string(), receiver: "remote-rcpt".to_string(), + v: Some(V2), }; let timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); assert_eq!( From ada7d114b837313ff95f2d7a9e29a8c3d904d1d9 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 9 Feb 2022 14:39:53 +0100 Subject: [PATCH 233/631] multi-test: allow type-complexity more granularly --- packages/multi-test/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 0ee12f501..543f07d3a 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -6,10 +6,9 @@ //! //! To understand the design of this module, please refer to `../DESIGN.md` -#![allow(clippy::type_complexity)] - mod app; mod bank; +#[allow(clippy::type_complexity)] mod contracts; pub mod custom_handler; pub mod error; From 6a396ffc8b2b8862d0e6ffe96c6ee5d3191a5830 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 9 Feb 2022 15:53:21 +0100 Subject: [PATCH 234/631] Set version: 0.12.0 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2ee01f14..5cf6e06fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -377,7 +377,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -394,7 +394,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-std", "criterion", @@ -405,7 +405,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -417,7 +417,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "anyhow", "assert_matches", @@ -463,7 +463,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "anyhow", "assert_matches", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -518,7 +518,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -529,7 +529,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -544,7 +544,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -561,7 +561,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -572,7 +572,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -590,7 +590,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -609,7 +609,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -620,7 +620,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.12.0-alpha2" +version = "0.12.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 6494b5ffa..03d923b1d 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0-alpha2", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw1 = { path = "../../packages/cw1", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0-alpha2", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index b25c75182..b7e9a3b61 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw1 = { path = "../../packages/cw1", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index d2608ff9e..8410d0bee 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw1 = { path = "../../packages/cw1", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw1 = { path = "../../packages/cw1", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index e97d4b92c..9debe3838 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw1155 = { path = "../../packages/cw1155", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index acf849c4a..f921749f4 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw20 = { path = "../../packages/cw20", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 765cc7035..4b7d932c1 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw20 = { path = "../../packages/cw20", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index b3478efdc..549945d60 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw3 = { path = "../../packages/cw3", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw3 = { path = "../../packages/cw3", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } -cw20-base = { path = "../cw20-base", version = "0.12.0-alpha2", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } +cw20 = { path = "../../packages/cw20", version = "0.12.0" } +cw20-base = { path = "../cw20-base", version = "0.12.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 0d5c2fa8f..3d1363329 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw3 = { path = "../../packages/cw3", version = "0.12.0-alpha2" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.0-alpha2", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw3 = { path = "../../packages/cw3", version = "0.12.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta3" } -cw4-group = { path = "../cw4-group", version = "0.12.0-alpha2" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0-alpha2" } +cw4-group = { path = "../cw4-group", version = "0.12.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 378fbc7d9..f0ac370da 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw4 = { path = "../../packages/cw4", version = "0.12.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index a6c662025..22236aa80 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw2 = { path = "../../packages/cw2", version = "0.12.0-alpha2" } -cw4 = { path = "../../packages/cw4", version = "0.12.0-alpha2" } -cw20 = { path = "../../packages/cw20", version = "0.12.0-alpha2" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw4 = { path = "../../packages/cw4", version = "0.12.0" } +cw20 = { path = "../../packages/cw20", version = "0.12.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 1c45b919e..90441dde6 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3" } -cw-utils = { path = "../utils", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../storage-plus", version = "0.12.0-alpha2" } +cw-utils = { path = "../utils", version = "0.12.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index ad9b3130c..b1fe8ab9e 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 1eae1e014..77ecaba69 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 6acf2984a..988f9ec33 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta3", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index a72bf47ec..8968aeaf8 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 9594a1376..c5666cf58 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } +cw-utils = { path = "../../packages/utils", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index a7baca6cd..1149f89c0 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } cosmwasm-std = { version = "1.0.0-beta3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index fdc5b00d7..fb3d94f56 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0-alpha2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2"} +cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0"} cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta3" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 3f5b57a9d..09dd27f7a 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 61013d1f0..e248bc12b 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.12.0-alpha2" +version = "0.12.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0-alpha2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } prost = "0.9" From 83ec69dfd3ac7d3f809ae9845085bc430d396f63 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 9 Feb 2022 16:25:33 +0100 Subject: [PATCH 235/631] Update CHANGELOG.md --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02ba4d208..850c883cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,19 +2,44 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha1...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha2...HEAD) + +**Breaking changes:** + +- Add `proposal_id` field to `VoteInfo` structure [\#647](https://github.com/CosmWasm/cw-plus/issues/647) + +**Merged pull requests:** + +- Ics20 same ack handling as ibctransfer [\#653](https://github.com/CosmWasm/cw-plus/pull/653) ([ethanfrey](https://github.com/ethanfrey)) +- packages: support custom queries [\#652](https://github.com/CosmWasm/cw-plus/pull/652) ([uint](https://github.com/uint)) +- CW20 - Fix Docs URL [\#649](https://github.com/CosmWasm/cw-plus/pull/649) ([entrancedjames](https://github.com/entrancedjames)) + +## [v0.12.0-alpha2](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha2) (2022-02-07) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/juno-ics20...v0.12.0-alpha2) **Closed issues:** - Incorrect Cw4ExecuteMsg used during remove\_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) +- \[cw3-flex/fixed-multisig\] Status changes after voting and proposal expiration [\#630](https://github.com/CosmWasm/cw-plus/issues/630) - Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) **Merged pull requests:** +- CW3: Add proposal\_id field to VoteInfo structure [\#648](https://github.com/CosmWasm/cw-plus/pull/648) ([ueco-jb](https://github.com/ueco-jb)) +- Use ContractInfoResponse from cosmwasm\_std [\#646](https://github.com/CosmWasm/cw-plus/pull/646) ([webmaster128](https://github.com/webmaster128)) +- Fix status/execution bugs in flex-multisig [\#643](https://github.com/CosmWasm/cw-plus/pull/643) ([uint](https://github.com/uint)) +- Set version: 0.12.0-alpha2 [\#642](https://github.com/CosmWasm/cw-plus/pull/642) ([ethanfrey](https://github.com/ethanfrey)) +- Allow modifying admin of Ics20 contract [\#641](https://github.com/CosmWasm/cw-plus/pull/641) ([ethanfrey](https://github.com/ethanfrey)) +- `MIGRATING.md` update / examples for type safe bounds [\#640](https://github.com/CosmWasm/cw-plus/pull/640) ([maurolacy](https://github.com/maurolacy)) - Fix benchmarks \(after 1.58.1 update\) [\#639](https://github.com/CosmWasm/cw-plus/pull/639) ([maurolacy](https://github.com/maurolacy)) - Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) ([maurolacy](https://github.com/maurolacy)) - Type safe bounds [\#627](https://github.com/CosmWasm/cw-plus/pull/627) ([maurolacy](https://github.com/maurolacy)) +## [juno-ics20](https://github.com/CosmWasm/cw-plus/tree/juno-ics20) (2022-01-27) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha1...juno-ics20) + ## [v0.12.0-alpha1](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha1) (2022-01-27) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...v0.12.0-alpha1) From c9870f2f8fecfff566d952fbeb3f87174528aa45 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 9 Feb 2022 18:43:55 +0100 Subject: [PATCH 236/631] Correct CHANGELOG --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 850c883cf..951033905 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,10 +36,6 @@ - Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) ([maurolacy](https://github.com/maurolacy)) - Type safe bounds [\#627](https://github.com/CosmWasm/cw-plus/pull/627) ([maurolacy](https://github.com/maurolacy)) -## [juno-ics20](https://github.com/CosmWasm/cw-plus/tree/juno-ics20) (2022-01-27) - -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha1...juno-ics20) - ## [v0.12.0-alpha1](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha1) (2022-01-27) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...v0.12.0-alpha1) From 35bc319c01a5a331238e34535e274b96dce0fba8 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 12 Feb 2022 14:44:31 +0100 Subject: [PATCH 237/631] query_admin: support custom queries --- packages/controllers/src/admin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/controllers/src/admin.rs b/packages/controllers/src/admin.rs index 49cef71cf..e503747a1 100644 --- a/packages/controllers/src/admin.rs +++ b/packages/controllers/src/admin.rs @@ -91,7 +91,7 @@ impl<'a> Admin<'a> { Ok(Response::new().add_attributes(attributes)) } - pub fn query_admin(&self, deps: Deps) -> StdResult { + pub fn query_admin(&self, deps: Deps) -> StdResult { let admin = self.get(deps)?.map(String::from); Ok(AdminResponse { admin }) } From 47d10aaa57186120b8205dc26000f92b4b2fade6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 12 Feb 2022 15:37:01 +0100 Subject: [PATCH 238/631] Fix: Forward original errors through anyhow in instantiate, execute, query --- packages/multi-test/src/app.rs | 24 ++++++++++++------------ packages/multi-test/src/contracts.rs | 23 ++++------------------- 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index f06ba6ac4..24f9be992 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2604,9 +2604,9 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 3 nested error types - // (the original error, initiate msg context, WasmMsg context) - assert_eq!(err.chain().count(), 3); + // We're expecting exactly 2 nested error types + // (the original error, WasmMsg context) + assert_eq!(err.chain().count(), 2); } #[test] @@ -2634,9 +2634,9 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 3 nested error types - // (the original error, execute msg context, WasmMsg context) - assert_eq!(err.chain().count(), 3); + // We're expecting exactly 2 nested error types + // (the original error, WasmMsg context) + assert_eq!(err.chain().count(), 2); } #[test] @@ -2674,9 +2674,9 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 4 nested error types - // (the original error, execute msg context, 2 WasmMsg contexts) - assert_eq!(err.chain().count(), 4); + // We're expecting exactly 3 nested error types + // (the original error, 2 WasmMsg contexts) + assert_eq!(err.chain().count(), 3); } #[test] @@ -2725,9 +2725,9 @@ mod test { panic!("wrong StdError variant"); } - // we're expecting exactly 5 nested error types - // (the original error, execute msg context, 3 WasmMsg contexts) - assert_eq!(err.chain().count(), 5); + // We're expecting exactly 4 nested error types + // (the original error, 3 WasmMsg contexts) + assert_eq!(err.chain().count(), 4); } } } diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 72bf76950..03c06bdc6 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -8,7 +8,7 @@ use cosmwasm_std::{ Response, SubMsg, }; -use anyhow::{anyhow, bail, Context, Result as AnyResult}; +use anyhow::{anyhow, bail, Result as AnyResult}; /// Interface to call into a Contract pub trait Contract @@ -349,12 +349,7 @@ where msg: Vec, ) -> AnyResult> { let msg: T1 = from_slice(&msg)?; - (self.execute_fn)(deps, env, info, msg.clone()) - .map_err(anyhow::Error::from) - .context(format!( - "Contract returned an error on execute msg:\n{:?}", - msg, - )) + (self.execute_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) } fn instantiate( @@ -365,22 +360,12 @@ where msg: Vec, ) -> AnyResult> { let msg: T2 = from_slice(&msg)?; - (self.instantiate_fn)(deps, env, info, msg.clone()) - .map_err(anyhow::Error::from) - .context(format!( - "Contract returned an error on instantiate msg:\n{:?}", - msg, - )) + (self.instantiate_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) } fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult { let msg: T3 = from_slice(&msg)?; - (self.query_fn)(deps, env, msg.clone()) - .map_err(anyhow::Error::from) - .context(format!( - "Contract returned an error on query msg:\n{:?}", - msg, - )) + (self.query_fn)(deps, env, msg).map_err(|err| anyhow!(err)) } // this returns an error if the contract doesn't implement sudo From 3da0e9058d1b80effbe51cef67043ce48328ed22 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 11 Feb 2022 22:54:00 +0100 Subject: [PATCH 239/631] Fix type annotations for IndexedMap/IndexedSnapshotMap prefixes --- packages/storage-plus/src/indexed_map.rs | 4 ++-- packages/storage-plus/src/indexed_snapshot.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 4033f2606..ee68c7549 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -172,11 +172,11 @@ where K: PrimaryKey<'a>, I: IndexList, { - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } - pub fn prefix(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } } diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 60029b1b0..2b152abb3 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -225,11 +225,11 @@ where K: PrimaryKey<'a>, I: IndexList, { - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { + pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } - pub fn prefix(&self, p: K::Prefix) -> Prefix { + pub fn prefix(&self, p: K::Prefix) -> Prefix { Prefix::new(self.pk_namespace, &p.prefix()) } } From ea6601ebfc694839b42f20dd33a2aa1fa215b1c8 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 12 Feb 2022 19:32:34 +0100 Subject: [PATCH 240/631] Fix type annotations for MultiIndex prefixes --- packages/storage-plus/src/indexes/multi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 89209718a..7cd7b4ebd 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -250,7 +250,7 @@ where T: Serialize + DeserializeOwned + Clone, IK: PrimaryKey<'a> + Prefixer<'a>, { - pub fn prefix(&self, p: IK) -> Prefix { + pub fn prefix(&self, p: IK) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), @@ -260,7 +260,7 @@ where ) } - pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix { + pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix { Prefix::with_deserialization_functions( self.idx_namespace, &p.prefix(), From 4dccbc45a49605e38d1879b2731a3a96c95fa9f0 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 13 Feb 2022 19:51:45 +0100 Subject: [PATCH 241/631] Update cosmwasm deps to latest version --- Cargo.lock | 20 ++++++++++---------- contracts/cw1-subkeys/Cargo.toml | 4 ++-- contracts/cw1-whitelist-ng/Cargo.toml | 4 ++-- contracts/cw1-whitelist/Cargo.toml | 4 ++-- contracts/cw1155-base/Cargo.toml | 4 ++-- contracts/cw20-base/Cargo.toml | 4 ++-- contracts/cw20-ics20/Cargo.toml | 4 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 4 ++-- contracts/cw3-flex-multisig/Cargo.toml | 4 ++-- contracts/cw4-group/Cargo.toml | 4 ++-- contracts/cw4-stake/Cargo.toml | 4 ++-- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 4 ++-- packages/cw1155/Cargo.toml | 4 ++-- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 4 ++-- packages/cw3/Cargo.toml | 4 ++-- packages/cw4/Cargo.toml | 4 ++-- packages/multi-test/Cargo.toml | 4 ++-- packages/storage-plus/Cargo.toml | 4 ++-- packages/utils/Cargo.toml | 2 +- 21 files changed, 47 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cf6e06fe..559efead0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,9 +155,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta3" +version = "1.0.0-beta5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a380b87642204557629c9b72988c47b55fbfe6d474960adba56b22331504956a" +checksum = "8904127a5b9e325ef5d6b2b3f997dcd74943cd35097139b1a4d15b1b6bccae66" dependencies = [ "digest", "ed25519-zebra", @@ -168,18 +168,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta3" +version = "1.0.0-beta5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866713b2fe13f23038c7d8824c3059d1f28dd94685fb406d1533c4eeeefeefae" +checksum = "a14364ac4d9d085867929d0cf3e94b1d2100121ce02c33c72961406830002613" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0-beta3" +version = "1.0.0-beta5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818b928263c09a3269c2bed22494a62107a43ef87900e273af8ad2cb9f7e4440" +checksum = "3b2941b87c42620d348e96ed05876bfda0dc1d5454a646d780d32f114c04921d" dependencies = [ "schemars", "serde_json", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.0.0-beta3" +version = "1.0.0-beta5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dbb9939b31441dfa9af3ec9740c8a24d585688401eff1b6b386abb7ad0d10a8" +checksum = "e2ece12e5bbde434b93937d7b2107e6291f11d69ffa72398c50e8bab41d451d3" dependencies = [ "base64", "cosmwasm-crypto", @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0-beta3" +version = "1.0.0-beta5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a4e55f0d64fed54cd2202301b8d466af8de044589247dabd77a4222f52f749" +checksum = "e7e4338d8e9934effa4594f139ce4e5f4b426796b70e2d53bb7e8605e9adf68c" dependencies = [ "cosmwasm-std", "serde", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 03d923b1d..a4d7abeae 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -23,7 +23,7 @@ cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw1 = { path = "../../packages/cw1", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index b7e9a3b61..30684f583 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -25,7 +25,7 @@ multitest = ["cw-multi-test", "anyhow"] cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw1 = { path = "../../packages/cw1", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -36,6 +36,6 @@ anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 8410d0bee..d05c32ad0 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw1 = { path = "../../packages/cw1", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 9debe3838..9b736dab9 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw1155 = { path = "../../packages/cw1155", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index f921749f4..2e28c0ede 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw20 = { path = "../../packages/cw20", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 4b7d932c1..e86437de4 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -21,7 +21,7 @@ library = [] cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw20 = { path = "../../packages/cw20", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3", features = ["stargate"] } +cosmwasm-std = { version = "1.0.0-beta5", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } schemars = "0.8.1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 549945d60..8f46b3d23 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -22,13 +22,13 @@ cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw3 = { path = "../../packages/cw3", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } cw20 = { path = "../../packages/cw20", version = "0.12.0" } cw20-base = { path = "../cw20-base", version = "0.12.0", features = ["library"] } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 3d1363329..bc75ce90a 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -24,12 +24,12 @@ cw3 = { path = "../../packages/cw3", version = "0.12.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } cw4-group = { path = "../cw4-group", version = "0.12.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index f0ac370da..e64646d4c 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -31,10 +31,10 @@ cw2 = { path = "../../packages/cw2", version = "0.12.0" } cw4 = { path = "../../packages/cw4", version = "0.12.0" } cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 22236aa80..27b1b90c5 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -32,10 +32,10 @@ cw4 = { path = "../../packages/cw4", version = "0.12.0" } cw20 = { path = "../../packages/cw20", version = "0.12.0" } cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 90441dde6..e72af5a7c 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } cw-utils = { path = "../utils", version = "0.12.0" } cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } schemars = "0.8.1" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index b1fe8ab9e..1dc3a5eec 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 77ecaba69..ec3f4d82b 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 988f9ec33..462b15b1a 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta3", default-features = false } +cosmwasm-std = { version = "1.0.0-beta5", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 8968aeaf8..a1584f630 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index c5666cf58..e42adfe8b 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 1149f89c0..0c2783953 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta3" } +cosmwasm-schema = { version = "1.0.0-beta5" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index fb3d94f56..52d33e018 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,8 +20,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0"} -cosmwasm-std = { version = "1.0.0-beta3", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } +cosmwasm-storage = { version = "1.0.0-beta5" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 09dd27f7a..926b7ad33 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -18,7 +18,7 @@ iterator = ["cosmwasm-std/iterator"] bench = false [dependencies] -cosmwasm-std = { version = "1.0.0-beta3", default-features = false } +cosmwasm-std = { version = "1.0.0-beta5", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -28,4 +28,4 @@ rand = "0.8" [[bench]] name = "main" -harness = false \ No newline at end of file +harness = false diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index e248bc12b..e452bc7e8 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta3" } +cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } From d8961d746f93b9f09dbe140320ab0d5d77367ed0 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 14 Feb 2022 09:33:27 +0100 Subject: [PATCH 242/631] Set version: 0.12.1 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 559efead0..b8c948bff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -377,7 +377,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.12.0" +version = "0.12.1" dependencies = [ "anyhow", "cosmwasm-std", @@ -394,7 +394,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-std", "criterion", @@ -405,7 +405,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -417,7 +417,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.12.0" +version = "0.12.1" dependencies = [ "anyhow", "assert_matches", @@ -463,7 +463,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.12.0" +version = "0.12.1" dependencies = [ "anyhow", "assert_matches", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -518,7 +518,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -529,7 +529,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -544,7 +544,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -561,7 +561,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -572,7 +572,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -590,7 +590,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -609,7 +609,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -620,7 +620,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.12.0" +version = "0.12.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index a4d7abeae..db313da0a 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw1 = { path = "../../packages/cw1", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw1 = { path = "../../packages/cw1", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta5" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 30684f583..89e20e1e9 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.12.0" +version = "0.12.1" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw1 = { path = "../../packages/cw1", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw1 = { path = "../../packages/cw1", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta5" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index d05c32ad0..ac7e9ed28 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw1 = { path = "../../packages/cw1", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw1 = { path = "../../packages/cw1", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta5" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 9b736dab9..e6197e527 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.12.0" +version = "0.12.1" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw1155 = { path = "../../packages/cw1155", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 2e28c0ede..03acef104 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw20 = { path = "../../packages/cw20", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw20 = { path = "../../packages/cw20", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index e86437de4..2b10d4857 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw20 = { path = "../../packages/cw20", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw20 = { path = "../../packages/cw20", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 8f46b3d23..b1388a00b 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw3 = { path = "../../packages/cw3", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw3 = { path = "../../packages/cw3", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta5" } -cw20 = { path = "../../packages/cw20", version = "0.12.0" } -cw20-base = { path = "../cw20-base", version = "0.12.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } +cw20 = { path = "../../packages/cw20", version = "0.12.1" } +cw20-base = { path = "../cw20-base", version = "0.12.1", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index bc75ce90a..e4f032420 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw3 = { path = "../../packages/cw3", version = "0.12.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw3 = { path = "../../packages/cw3", version = "0.12.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.1", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta5" } -cw4-group = { path = "../cw4-group", version = "0.12.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.0" } +cw4-group = { path = "../cw4-group", version = "0.12.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index e64646d4c..b2038f155 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw4 = { path = "../../packages/cw4", version = "0.12.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw4 = { path = "../../packages/cw4", version = "0.12.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 27b1b90c5..a3086f48c 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw2 = { path = "../../packages/cw2", version = "0.12.0" } -cw4 = { path = "../../packages/cw4", version = "0.12.0" } -cw20 = { path = "../../packages/cw20", version = "0.12.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw4 = { path = "../../packages/cw4", version = "0.12.1" } +cw20 = { path = "../../packages/cw20", version = "0.12.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index e72af5a7c..17ee89281 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta5" } -cw-utils = { path = "../utils", version = "0.12.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } +cw-utils = { path = "../utils", version = "0.12.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 1dc3a5eec..8b3017c2d 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index ec3f4d82b..e81f36c92 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.12.0" +version = "0.12.1" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 462b15b1a..675d2ecfe 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta5", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index a1584f630..c24708e85 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index e42adfe8b..98dcc64af 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } +cw-utils = { path = "../../packages/utils", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 0c2783953..77c20b649 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } cosmwasm-std = { version = "1.0.0-beta5" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 52d33e018..f39042c1d 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0"} +cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1"} cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta5" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 926b7ad33..1e22dd983 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index e452bc7e8..f2ab10026 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.12.0" +version = "0.12.1" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } prost = "0.9" From fbf5617099f65d12b50f19b41ad3b455c241c505 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 14 Feb 2022 09:38:10 +0100 Subject: [PATCH 243/631] cargo update --- Cargo.lock | 110 ++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8c948bff..b8c4ce5e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.51" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" dependencies = [ "backtrace", ] @@ -45,15 +45,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" +checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" dependencies = [ "addr2line", "cc", @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byteorder" @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ "cfg-if", "crossbeam-utils", @@ -279,9 +279,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ "cfg-if", "crossbeam-utils", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ "cfg-if", "lazy_static", @@ -746,9 +746,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -767,9 +767,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -847,9 +847,9 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] @@ -874,9 +874,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "log" @@ -998,9 +998,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.34" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -1030,9 +1030,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.10" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -1074,7 +1074,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] @@ -1194,15 +1194,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] @@ -1228,9 +1228,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -1250,9 +1250,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa 1.0.1", "ryu", @@ -1261,9 +1261,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer", "cfg-if", @@ -1305,9 +1305,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -1355,9 +1355,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uint" @@ -1385,9 +1385,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" @@ -1414,9 +1414,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1424,9 +1424,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", @@ -1439,9 +1439,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1449,9 +1449,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", "quote", @@ -1462,15 +1462,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", From b6d804c687b4d27f86d265270c77537ef527f5de Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 14 Feb 2022 09:44:34 +0100 Subject: [PATCH 244/631] Update CHANGELOG --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 951033905..e42ea3b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,39 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha2...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha3...HEAD) + +**Merged pull requests:** + +- Fix missing custom query [\#657](https://github.com/CosmWasm/cw-plus/pull/657) ([maurolacy](https://github.com/maurolacy)) +- Forward original errors in multitest `instantiate`, `execute` and `query` [\#656](https://github.com/CosmWasm/cw-plus/pull/656) ([maurolacy](https://github.com/maurolacy)) +- Fix missing prefix bound types [\#655](https://github.com/CosmWasm/cw-plus/pull/655) ([maurolacy](https://github.com/maurolacy)) + +## [v0.12.0-alpha3](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha3) (2022-02-10) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...v0.12.0-alpha3) + +## [v0.12.0](https://github.com/CosmWasm/cw-plus/tree/v0.12.0) (2022-02-09) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha2...v0.12.0) **Breaking changes:** - Add `proposal_id` field to `VoteInfo` structure [\#647](https://github.com/CosmWasm/cw-plus/issues/647) +**Deprecated:** + +- Remove `IntKey` with surrounding implementation [\#570](https://github.com/CosmWasm/cw-plus/issues/570) + +**Closed issues:** + +- Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) +- Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) +- Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) + **Merged pull requests:** +- Prepare release v0.12.0 [\#654](https://github.com/CosmWasm/cw-plus/pull/654) ([uint](https://github.com/uint)) - Ics20 same ack handling as ibctransfer [\#653](https://github.com/CosmWasm/cw-plus/pull/653) ([ethanfrey](https://github.com/ethanfrey)) - packages: support custom queries [\#652](https://github.com/CosmWasm/cw-plus/pull/652) ([uint](https://github.com/uint)) - CW20 - Fix Docs URL [\#649](https://github.com/CosmWasm/cw-plus/pull/649) ([entrancedjames](https://github.com/entrancedjames)) From 0383c6462bb463f82fe08af566863b803d97cc29 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 14 Feb 2022 09:47:24 +0100 Subject: [PATCH 245/631] Consolidate v0.12.0 entries --- CHANGELOG.md | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e42ea3b2b..5d7701510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha3...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...HEAD) **Merged pull requests:** @@ -10,13 +10,9 @@ - Forward original errors in multitest `instantiate`, `execute` and `query` [\#656](https://github.com/CosmWasm/cw-plus/pull/656) ([maurolacy](https://github.com/maurolacy)) - Fix missing prefix bound types [\#655](https://github.com/CosmWasm/cw-plus/pull/655) ([maurolacy](https://github.com/maurolacy)) -## [v0.12.0-alpha3](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha3) (2022-02-10) - -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...v0.12.0-alpha3) - ## [v0.12.0](https://github.com/CosmWasm/cw-plus/tree/v0.12.0) (2022-02-09) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0-alpha2...v0.12.0) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...v0.12.0) **Breaking changes:** @@ -31,6 +27,11 @@ - Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) - Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) - Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) +- Incorrect Cw4ExecuteMsg used during remove\_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) +- \[cw3-flex/fixed-multisig\] Status changes after voting and proposal expiration [\#630](https://github.com/CosmWasm/cw-plus/issues/630) +- Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) +- Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) +- Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) **Merged pull requests:** @@ -38,19 +39,6 @@ - Ics20 same ack handling as ibctransfer [\#653](https://github.com/CosmWasm/cw-plus/pull/653) ([ethanfrey](https://github.com/ethanfrey)) - packages: support custom queries [\#652](https://github.com/CosmWasm/cw-plus/pull/652) ([uint](https://github.com/uint)) - CW20 - Fix Docs URL [\#649](https://github.com/CosmWasm/cw-plus/pull/649) ([entrancedjames](https://github.com/entrancedjames)) - -## [v0.12.0-alpha2](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha2) (2022-02-07) - -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/juno-ics20...v0.12.0-alpha2) - -**Closed issues:** - -- Incorrect Cw4ExecuteMsg used during remove\_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) -- \[cw3-flex/fixed-multisig\] Status changes after voting and proposal expiration [\#630](https://github.com/CosmWasm/cw-plus/issues/630) -- Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) - -**Merged pull requests:** - - CW3: Add proposal\_id field to VoteInfo structure [\#648](https://github.com/CosmWasm/cw-plus/pull/648) ([ueco-jb](https://github.com/ueco-jb)) - Use ContractInfoResponse from cosmwasm\_std [\#646](https://github.com/CosmWasm/cw-plus/pull/646) ([webmaster128](https://github.com/webmaster128)) - Fix status/execution bugs in flex-multisig [\#643](https://github.com/CosmWasm/cw-plus/pull/643) ([uint](https://github.com/uint)) @@ -60,22 +48,6 @@ - Fix benchmarks \(after 1.58.1 update\) [\#639](https://github.com/CosmWasm/cw-plus/pull/639) ([maurolacy](https://github.com/maurolacy)) - Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) ([maurolacy](https://github.com/maurolacy)) - Type safe bounds [\#627](https://github.com/CosmWasm/cw-plus/pull/627) ([maurolacy](https://github.com/maurolacy)) - -## [v0.12.0-alpha1](https://github.com/CosmWasm/cw-plus/tree/v0.12.0-alpha1) (2022-01-27) - -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.11.1...v0.12.0-alpha1) - -**Deprecated:** - -- Remove `IntKey` with surrounding implementation [\#570](https://github.com/CosmWasm/cw-plus/issues/570) - -**Closed issues:** - -- Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) -- Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) - -**Merged pull requests:** - - Update Rust to v1.54.0 in CI [\#636](https://github.com/CosmWasm/cw-plus/pull/636) ([maurolacy](https://github.com/maurolacy)) - Refactor cw2 spec readme [\#635](https://github.com/CosmWasm/cw-plus/pull/635) ([orkunkl](https://github.com/orkunkl)) - Fix tag consolidation for matching CHANGELOG entries [\#634](https://github.com/CosmWasm/cw-plus/pull/634) ([maurolacy](https://github.com/maurolacy)) From d2ff1083c986ff0fe186db494e8ebaf295938cfe Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 14 Feb 2022 09:48:21 +0100 Subject: [PATCH 246/631] Add entry for upcoming v0.12.1 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d7701510..731c7c808 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,11 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.1...HEAD) + +## [v0.12.1](https://github.com/CosmWasm/cw-plus/tree/v0.12.1) (2022-02-14) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...v0.12.1) **Merged pull requests:** From 94bcbc600d6bdace4ddc69d7b93fea3c7b354fb3 Mon Sep 17 00:00:00 2001 From: Harry Scholes Date: Tue, 15 Feb 2022 12:51:48 +0200 Subject: [PATCH 247/631] cw20-base: validate addresses are unique in initial balances --- contracts/cw20-base/src/contract.rs | 49 ++++++++++++++++++++++++++--- contracts/cw20-base/src/error.rs | 3 ++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 32076c451..72f7b3d53 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -151,16 +151,34 @@ pub fn instantiate( Ok(Response::default()) } -pub fn create_accounts(deps: &mut DepsMut, accounts: &[Cw20Coin]) -> StdResult { +pub fn create_accounts( + deps: &mut DepsMut, + accounts: &[Cw20Coin], +) -> Result { + validate_accounts(accounts)?; + let mut total_supply = Uint128::zero(); for row in accounts { let address = deps.api.addr_validate(&row.address)?; BALANCES.save(deps.storage, &address, &row.amount)?; total_supply += row.amount; } + Ok(total_supply) } +pub fn validate_accounts(accounts: &[Cw20Coin]) -> Result<(), ContractError> { + let mut addresses = accounts.iter().map(|c| &c.address).collect::>(); + addresses.sort(); + addresses.dedup(); + + if addresses.len() != accounts.len() { + Err(ContractError::DuplicateInitialBalanceAddresses {}) + } else { + Ok(()) + } +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, @@ -875,6 +893,32 @@ mod tests { let addr1 = String::from("addr0001"); let amount2 = Uint128::from(7890987u128); let addr2 = String::from("addr0002"); + let info = mock_info("creator", &[]); + let env = mock_env(); + + // Fails with duplicate addresses + let instantiate_msg = InstantiateMsg { + name: "Bash Shell".to_string(), + symbol: "BASH".to_string(), + decimals: 6, + initial_balances: vec![ + Cw20Coin { + address: addr1.clone(), + amount: amount1, + }, + Cw20Coin { + address: addr1.clone(), + amount: amount2, + }, + ], + mint: None, + marketing: None, + }; + let err = + instantiate(deps.as_mut(), env.clone(), info.clone(), instantiate_msg).unwrap_err(); + assert_eq!(err, ContractError::DuplicateInitialBalanceAddresses {}); + + // Works with unique addresses let instantiate_msg = InstantiateMsg { name: "Bash Shell".to_string(), symbol: "BASH".to_string(), @@ -892,11 +936,8 @@ mod tests { mint: None, marketing: None, }; - let info = mock_info("creator", &[]); - let env = mock_env(); let res = instantiate(deps.as_mut(), env, info, instantiate_msg).unwrap(); assert_eq!(0, res.messages.len()); - assert_eq!( query_token_info(deps.as_ref()).unwrap(), TokenInfoResponse { diff --git a/contracts/cw20-base/src/error.rs b/contracts/cw20-base/src/error.rs index 264f3756d..a1a63967d 100644 --- a/contracts/cw20-base/src/error.rs +++ b/contracts/cw20-base/src/error.rs @@ -32,4 +32,7 @@ pub enum ContractError { #[error("Invalid png header")] InvalidPngHeader {}, + + #[error("Duplicate initial balance addresses")] + DuplicateInitialBalanceAddresses {}, } From f16f391f46aa5253b0ea57feef514f5b743eec19 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 16 Feb 2022 22:24:50 +0100 Subject: [PATCH 248/631] Make ContractWrapper::new_with_empty convert Deps to Deps --- packages/multi-test/src/contracts.rs | 51 ++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 03c06bdc6..8ed6e507e 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -2,10 +2,11 @@ use schemars::JsonSchema; use serde::de::DeserializeOwned; use std::error::Error; use std::fmt::{self, Debug, Display}; +use std::ops::Deref; use cosmwasm_std::{ - from_slice, Binary, CosmosMsg, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, Reply, - Response, SubMsg, + from_slice, Binary, CosmosMsg, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, + QuerierWrapper, Reply, Response, SubMsg, }; use anyhow::{anyhow, bail, Result as AnyResult}; @@ -121,14 +122,14 @@ where /// this will take a contract that returns Response and will "upgrade" it /// to Response if needed to be compatible with a chain-specific extension pub fn new_with_empty( - execute_fn: ContractFn, - instantiate_fn: ContractFn, - query_fn: QueryFn, + execute_fn: ContractFn, + instantiate_fn: ContractFn, + query_fn: QueryFn, ) -> Self { Self { execute_fn: customize_fn(execute_fn), instantiate_fn: customize_fn(instantiate_fn), - query_fn: Box::new(query_fn), + query_fn: customize_query(query_fn), sudo_fn: None, reply_fn: None, migrate_fn: None, @@ -261,7 +262,7 @@ where } } -fn customize_fn(raw_fn: ContractFn) -> ContractClosure +fn customize_fn(raw_fn: ContractFn) -> ContractClosure where T: DeserializeOwned + 'static, E: Display + Debug + Send + Sync + 'static, @@ -270,11 +271,47 @@ where { let customized = move |deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { + let deps = decustomize_deps_mut(deps); raw_fn(deps, env, info, msg).map(customize_response::) }; Box::new(customized) } +fn customize_query(raw_fn: QueryFn) -> QueryClosure +where + T: DeserializeOwned + 'static, + E: Display + Debug + Send + Sync + 'static, + Q: CustomQuery + DeserializeOwned + 'static, +{ + let customized = move |deps: Deps, env: Env, msg: T| -> Result { + let deps = decustomize_deps(deps); + raw_fn(deps, env, msg) + }; + Box::new(customized) +} + +fn decustomize_deps_mut(deps: DepsMut) -> DepsMut +where + Q: CustomQuery + DeserializeOwned + 'static, +{ + DepsMut { + storage: deps.storage, + api: deps.api, + querier: QuerierWrapper::new(deps.querier.deref()), + } +} + +fn decustomize_deps(deps: Deps) -> Deps +where + Q: CustomQuery + DeserializeOwned + 'static, +{ + Deps { + storage: deps.storage, + api: deps.api, + querier: QuerierWrapper::new(deps.querier.deref()), + } +} + fn customize_permissioned_fn( raw_fn: PermissionedFn, ) -> PermissionedClosure From 290a87f284d141ef852c0da4bfec2f7a9ddc63f4 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 16 Feb 2022 22:29:27 +0100 Subject: [PATCH 249/631] Fixed lifetime issues --- packages/multi-test/src/contracts.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 8ed6e507e..182e335b1 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -270,8 +270,8 @@ where Q: CustomQuery + DeserializeOwned + 'static, { let customized = - move |deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { - let deps = decustomize_deps_mut(deps); + move |mut deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { + let deps = decustomize_deps_mut(&mut deps); raw_fn(deps, env, info, msg).map(customize_response::) }; Box::new(customized) @@ -284,13 +284,13 @@ where Q: CustomQuery + DeserializeOwned + 'static, { let customized = move |deps: Deps, env: Env, msg: T| -> Result { - let deps = decustomize_deps(deps); + let deps = decustomize_deps(&deps); raw_fn(deps, env, msg) }; Box::new(customized) } -fn decustomize_deps_mut(deps: DepsMut) -> DepsMut +fn decustomize_deps_mut<'a, Q>(deps: &'a mut DepsMut) -> DepsMut<'a, Empty> where Q: CustomQuery + DeserializeOwned + 'static, { @@ -301,7 +301,7 @@ where } } -fn decustomize_deps(deps: Deps) -> Deps +fn decustomize_deps<'a, Q>(deps: &'a Deps<'a, Q>) -> Deps<'a, Empty> where Q: CustomQuery + DeserializeOwned + 'static, { From 775439476a5b353b38e287163482dff20b2bd010 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 17 Feb 2022 10:05:42 +0100 Subject: [PATCH 250/631] cargo fmt --- packages/multi-test/src/contracts.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 182e335b1..68ef4c30b 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -269,11 +269,14 @@ where C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, Q: CustomQuery + DeserializeOwned + 'static, { - let customized = - move |mut deps: DepsMut, env: Env, info: MessageInfo, msg: T| -> Result, E> { - let deps = decustomize_deps_mut(&mut deps); - raw_fn(deps, env, info, msg).map(customize_response::) - }; + let customized = move |mut deps: DepsMut, + env: Env, + info: MessageInfo, + msg: T| + -> Result, E> { + let deps = decustomize_deps_mut(&mut deps); + raw_fn(deps, env, info, msg).map(customize_response::) + }; Box::new(customized) } From 94d879fe259a85670c9547996a3a81e4ba40d023 Mon Sep 17 00:00:00 2001 From: Sturdy Date: Thu, 17 Feb 2022 16:07:31 +0100 Subject: [PATCH 251/631] fix: Remove old TODO comment in cw3-flex README --- contracts/cw3-flex-multisig/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/cw3-flex-multisig/README.md b/contracts/cw3-flex-multisig/README.md index 8ca79ccb6..3225d94d1 100644 --- a/contracts/cw3-flex-multisig/README.md +++ b/contracts/cw3-flex-multisig/README.md @@ -64,10 +64,6 @@ be reverted, and it will remain "Passed", so you can try again). Once a proposal has expired without passing, anyone can submit a "Close" message to mark it closed. This has no effect beyond cleaning up the UI/database. -TODO: this contract currently assumes the group membership is static during -the lifetime of one proposal. If the membership changes when a proposal is -open, this will calculate incorrect values (future PR). - ## Running this contract You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. From f48dbce8ad4f3656f93996fb386b1bae95b45cfa Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Tue, 22 Feb 2022 15:06:33 +0000 Subject: [PATCH 252/631] Reject proposals when they cannot pass. --- contracts/cw3-fixed-multisig/src/contract.rs | 50 +++++ contracts/cw3-fixed-multisig/src/state.rs | 203 +++++++++++++++++-- 2 files changed, 241 insertions(+), 12 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 8c2f530c7..ca7ff955a 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -764,6 +764,56 @@ mod tests { let info = mock_info(VOTER5, &[]); let err = execute(deps.as_mut(), mock_env(), info, yes_vote).unwrap_err(); assert_eq!(err, ContractError::NotOpen {}); + + // Propose + let info = mock_info(OWNER, &[]); + let bank_msg = BankMsg::Send { + to_address: SOMEBODY.into(), + amount: vec![coin(1, "BTC")], + }; + let msgs = vec![CosmosMsg::Bank(bank_msg)]; + let proposal = ExecuteMsg::Propose { + title: "Pay somebody".to_string(), + description: "Do I pay her?".to_string(), + msgs, + latest: None, + }; + let res = execute(deps.as_mut(), mock_env(), info.clone(), proposal).unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.attributes[2].value.parse().unwrap(); + + // Cast a No vote + let no_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::No, + }; + // Voter1 vote no + let info = mock_info(VOTER1, &[]); + let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); + + // Verify it is not enough to reject yet + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER1) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Open") + ); + + let info = mock_info(VOTER4, &[]); + let res = execute(deps.as_mut(), mock_env(), info, no_vote).unwrap(); + + // Verify it is now rejected due to reaching threshold + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER4) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Rejected") + ); } #[test] diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 92dbbe62f..6e1eacb04 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -47,6 +47,9 @@ impl Proposal { if status == Status::Open && self.expires.is_expired(block) { status = Status::Rejected; } + if status == Status::Open && self.is_rejected(block) { + status = Status::Rejected; + } status } @@ -57,17 +60,24 @@ impl Proposal { self.status = self.current_status(block); } - // returns true iff this proposal is sure to pass (even before expiration if no future - // sequence of possible votes can cause it to fail) - pub fn is_passed(&self, block: &BlockInfo) -> bool { + /// Helper function to check if a certain vote count has reached threshold. + /// Only called from is_rejected and is_passed for no and yes votes + /// Handles the different threshold types accordingly. + /// This function returns true if and only if vote_count is greater than the threshold which + /// is calculated. + /// In the case where we use yes votes, this function will return true if and only if the + /// proposal will pass. + /// In the case where we use no votes, this function will return true if and only if the + /// proposal will be rejected regardless of other votes. + fn does_vote_count_reach_threshold(&self, vote_count: u64, block: &BlockInfo) -> bool { match self.threshold { Threshold::AbsoluteCount { weight: weight_needed, - } => self.votes.yes >= weight_needed, + } => vote_count >= weight_needed, Threshold::AbsolutePercentage { percentage: percentage_needed, } => { - self.votes.yes + vote_count >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) } Threshold::ThresholdQuorum { threshold, quorum } => { @@ -76,18 +86,30 @@ impl Proposal { return false; } if self.expires.is_expired(block) { - // If expired, we compare Yes votes against the total number of votes (minus abstain). + // If expired, we compare vote_count against the total number of votes (minus abstain). let opinions = self.votes.total() - self.votes.abstain; - self.votes.yes >= votes_needed(opinions, threshold) + vote_count >= votes_needed(opinions, threshold) } else { - // If not expired, we must assume all non-votes will be cast as No. - // We compare threshold against the total weight (minus abstain). + // If not expired, we must assume all non-votes will be cast against + // vote_count let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.yes >= votes_needed(possible_opinions, threshold) + vote_count >= votes_needed(possible_opinions, threshold) } } } } + + /// returns true iff this proposal is sure to pass (even before expiration if no future + /// sequence of possible votes can cause it to fail) + pub fn is_passed(&self, block: &BlockInfo) -> bool { + self.does_vote_count_reach_threshold(self.votes.yes, block) + } + + /// As above for the rejected check, used to check if a proposal is + /// already rejected. + pub fn is_rejected(&self, block: &BlockInfo) -> bool { + self.does_vote_count_reach_threshold(self.votes.no, block) + } } // weight of votes for each option @@ -192,12 +214,12 @@ mod test { assert_eq!(12, votes_needed(48, Decimal::percent(25))); } - fn check_is_passed( + fn setup_prop( threshold: Threshold, votes: Votes, total_weight: u64, is_expired: bool, - ) -> bool { + ) -> (Proposal, BlockInfo) { let block = mock_env().block; let expires = match is_expired { true => Expiration::AtHeight(block.height - 5), @@ -214,9 +236,30 @@ mod test { total_weight, votes, }; + + (prop, block) + } + + fn check_is_passed( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> bool { + let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); prop.is_passed(&block) } + fn check_is_rejected( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> bool { + let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); + prop.is_rejected(&block) + } + #[test] fn proposal_passed_absolute_count() { let fixed = Threshold::AbsoluteCount { weight: 10 }; @@ -231,6 +274,21 @@ mod test { assert!(check_is_passed(fixed, votes, 30, true)); } + #[test] + fn proposal_rejected_absolute_count() { + let fixed = Threshold::AbsoluteCount { weight: 10 }; + let mut votes = Votes::yes(0); + votes.add_vote(Vote::Veto, 4); + votes.add_vote(Vote::No, 7); + // same expired or not, total_weight or whatever + assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, false)); + assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, true)); + // a few more no votes and we have rejected the prop + votes.add_vote(Vote::No, 3); + assert!(check_is_rejected(fixed.clone(), votes.clone(), 30, false)); + assert!(check_is_rejected(fixed, votes, 30, true)); + } + #[test] fn proposal_passed_absolute_percentage() { let percent = Threshold::AbsolutePercentage { @@ -251,6 +309,38 @@ mod test { assert!(check_is_passed(percent, votes, 14, true)); } + #[test] + fn proposal_rejected_absolute_percentage() { + let percent = Threshold::AbsolutePercentage { + percentage: Decimal::percent(50), + }; + + // 4 YES, 7 NO, 2 ABSTAIN + let mut votes = Votes::yes(4); + votes.add_vote(Vote::No, 7); + votes.add_vote(Vote::Abstain, 2); + + // 15 total voting power + // 7 / (15 - 2) > 50% + // Expiry does not matter + assert!(check_is_rejected(percent.clone(), votes.clone(), 15, false)); + assert!(check_is_rejected(percent.clone(), votes.clone(), 15, true)); + + // 17 total voting power + // 7 / (17 - 2) < 50% + assert!(!check_is_rejected( + percent.clone(), + votes.clone(), + 17, + false + )); + assert!(!check_is_rejected(percent.clone(), votes.clone(), 17, true)); + + // Rejected if total was lower + assert!(check_is_rejected(percent.clone(), votes.clone(), 14, false)); + assert!(check_is_rejected(percent, votes.clone(), 14, true)); + } + #[test] fn proposal_passed_quorum() { let quorum = Threshold::ThresholdQuorum { @@ -318,6 +408,95 @@ mod test { assert!(check_is_passed(quorum, passing, 16, false)); } + #[test] + fn proposal_rejected_quorum() { + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(50), + quorum: Decimal::percent(40), + }; + // all non-yes votes are counted for quorum + let rejecting = Votes { + yes: 3, + no: 7, + abstain: 2, + veto: 1, + }; + // abstain votes are not counted for threshold => yes / (yes + no + veto) + let rejected_ignoring_abstain = Votes { + yes: 4, + no: 6, + abstain: 5, + veto: 2, + }; + // fails any way you look at it + let failing = Votes { + yes: 5, + no: 6, + abstain: 2, + veto: 2, + }; + + // first, expired (voting period over) + // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 30, + true + )); + // Under quorum means it cannot be rejected + assert!(!check_is_rejected( + quorum.clone(), + rejecting.clone(), + 33, + true + )); + + // over quorum, threshold passes if we ignore abstain + // 17 total votes w/ abstain => 40% quorum of 40 total + // 6 no / (6 no + 4 yes + 2 votes) => 50% threshold + assert!(check_is_rejected( + quorum.clone(), + rejected_ignoring_abstain.clone(), + 40, + true + )); + + // over quorum, but under threshold fails also + assert!(!check_is_rejected(quorum.clone(), failing, 20, true)); + + // Voting is still open so assume rest of votes are yes + // threshold not reached + assert!(!check_is_rejected( + quorum.clone(), + rejecting.clone(), + 30, + false + )); + assert!(!check_is_rejected( + quorum.clone(), + rejected_ignoring_abstain.clone(), + 40, + false + )); + // if we have threshold * total_weight as no votes this must reject + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 14, + false + )); + // all votes have been cast, some abstain + assert!(check_is_rejected( + quorum.clone(), + rejected_ignoring_abstain, + 17, + false + )); + // 3 votes uncast, if they all vote yes, we have 7 no, 7 yes+veto, 2 abstain (out of 16) + assert!(check_is_rejected(quorum, rejecting, 16, false)); + } + #[test] fn quorum_edge_cases() { // when we pass absolute threshold (everyone else voting no, we pass), but still don't hit quorum From a46886e1c524c9b9d4eb91d8f812694d530de557 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Tue, 22 Feb 2022 15:13:08 +0000 Subject: [PATCH 253/631] lint --- contracts/cw3-fixed-multisig/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index ca7ff955a..f55609bfe 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -778,7 +778,7 @@ mod tests { msgs, latest: None, }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), proposal).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info, proposal).unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.attributes[2].value.parse().unwrap(); From f770502a3f0b0d22ad973301e42429ffe8c8dde5 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Tue, 22 Feb 2022 15:19:57 +0000 Subject: [PATCH 254/631] Add flex tests --- contracts/cw3-flex-multisig/src/contract.rs | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 236358c66..bd6a78dbd 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1056,6 +1056,39 @@ mod tests { .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) .unwrap(); assert!(vote.vote.is_none()); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Cast a No vote + let no_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::No, + }; + let _ = app + .execute_contract(Addr::unchecked(VOTER2), flex_addr.clone(), &no_vote, &[]) + .unwrap(); + + // Powerful voter supports it, so it rejects + let res = app + .execute_contract(Addr::unchecked(VOTER4), flex_addr, &no_vote, &[]) + .unwrap(); + + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER4), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Rejected"), + ], + ); } #[test] From 8cb9e80e472a37a30f31fa8d1aa3091315d7411f Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Tue, 22 Feb 2022 16:54:53 +0000 Subject: [PATCH 255/631] Address feedback --- contracts/cw3-fixed-multisig/src/state.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 6e1eacb04..361187dc4 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -44,10 +44,7 @@ impl Proposal { if status == Status::Open && self.is_passed(block) { status = Status::Passed; } - if status == Status::Open && self.expires.is_expired(block) { - status = Status::Rejected; - } - if status == Status::Open && self.is_rejected(block) { + if status == Status::Open && (self.is_rejected(block) || self.expires.is_expired(block)) { status = Status::Rejected; } @@ -65,9 +62,8 @@ impl Proposal { /// Handles the different threshold types accordingly. /// This function returns true if and only if vote_count is greater than the threshold which /// is calculated. - /// In the case where we use yes votes, this function will return true if and only if the - /// proposal will pass. - /// In the case where we use no votes, this function will return true if and only if the + /// In the case where we use yes votes, this function will return true if the proposal will pass. + /// In the case where we use no votes, this function will return true if the /// proposal will be rejected regardless of other votes. fn does_vote_count_reach_threshold(&self, vote_count: u64, block: &BlockInfo) -> bool { match self.threshold { @@ -99,14 +95,14 @@ impl Proposal { } } - /// returns true iff this proposal is sure to pass (even before expiration if no future - /// sequence of possible votes can cause it to fail) + /// Returns true if this proposal is sure to pass (even before expiration, if no future + /// sequence of possible votes could cause it to fail). pub fn is_passed(&self, block: &BlockInfo) -> bool { self.does_vote_count_reach_threshold(self.votes.yes, block) } - /// As above for the rejected check, used to check if a proposal is - /// already rejected. + /// Returns true if this proposal is sure to be rejected (even before expiration, if + /// no future sequence of possible votes could cause it to fail). pub fn is_rejected(&self, block: &BlockInfo) -> bool { self.does_vote_count_reach_threshold(self.votes.no, block) } From a231a2ede89bb1db29ba04a0db186077ddb96056 Mon Sep 17 00:00:00 2001 From: Callum Anderson <46447937+Callum-A@users.noreply.github.com> Date: Wed, 23 Feb 2022 11:35:01 +0000 Subject: [PATCH 256/631] Update contracts/cw3-flex-multisig/src/contract.rs Co-authored-by: Mauro Lacy --- contracts/cw3-flex-multisig/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index bd6a78dbd..5616cba7d 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1075,7 +1075,7 @@ mod tests { .execute_contract(Addr::unchecked(VOTER2), flex_addr.clone(), &no_vote, &[]) .unwrap(); - // Powerful voter supports it, so it rejects + // Powerful voter opposes it, so it rejects let res = app .execute_contract(Addr::unchecked(VOTER4), flex_addr, &no_vote, &[]) .unwrap(); From 4cc1159dfda17dbe50c1fa28b27a6489a5bb032d Mon Sep 17 00:00:00 2001 From: Callum Anderson <46447937+Callum-A@users.noreply.github.com> Date: Wed, 23 Feb 2022 11:35:10 +0000 Subject: [PATCH 257/631] Update contracts/cw3-fixed-multisig/src/state.rs Co-authored-by: Mauro Lacy --- contracts/cw3-fixed-multisig/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 361187dc4..e808da7de 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -102,7 +102,7 @@ impl Proposal { } /// Returns true if this proposal is sure to be rejected (even before expiration, if - /// no future sequence of possible votes could cause it to fail). + /// no future sequence of possible votes could cause it to pass). pub fn is_rejected(&self, block: &BlockInfo) -> bool { self.does_vote_count_reach_threshold(self.votes.no, block) } From 73fcd8a84e51c299cc65a235d5ba1c57d8ea9937 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 22 Feb 2022 22:59:08 +0100 Subject: [PATCH 258/631] Update storage-plus README Add entry / notes about mutli-index type-safe bounds --- packages/storage-plus/README.md | 78 ++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index edb17d8ed..04fa94556 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -7,9 +7,8 @@ more powerful and easy to use interfaces. Here are those interfaces. **Status: beta** This has been heavily used in many production-quality contracts and -heavily refined. There is one planned API break (dealing with -auto-deserializing keys in range queries), but the code has demonstrated -itself to be stable and powerful. Please feel free to use in your contracts. +heavily refined. The code has demonstrated itself to be stable and powerful. +Please feel free to use it in your contracts. ## Usage Overview @@ -98,7 +97,7 @@ fn demo() -> StdResult<()> { ## Map -The usage of an [`Map`](./src/item.rs) is a little more complex, but +The usage of a [`Map`](./src/map.rs) is a little more complex, but is still pretty straight-forward. You can imagine it as a storage-backed `BTreeMap`, allowing key-value lookups with typed values. In addition, we support not only simple binary keys (`&[u8]`), but tuples, which are @@ -119,7 +118,7 @@ variants of the object, just one type. Furthermore, we use `const fn` to create the `Bucket`, allowing it to be defined as a global compile-time constant rather than a function that must be constructed each time, which saves gas as well as typing. In addition, the composite indexes -(tuples) is more ergonomic and expressive of intention, and the range +(tuples) are more ergonomic and expressive of intention, and the range interface has been improved. Here is an example with normal (simple) keys: @@ -189,7 +188,7 @@ fn demo() -> StdResult<()> { ### Key types A `Map` key can be anything that implements the `PrimaryKey` trait. There are a series of implementations of -`PrimaryKey` already provided (see `packages/storage-plus/src/keys.rs`): +`PrimaryKey` already provided (see [keys.rs](src/keys.rs)): - `impl<'a> PrimaryKey<'a> for &'a [u8]` - `impl<'a> PrimaryKey<'a> for &'a str` @@ -199,10 +198,11 @@ A `Map` key can be anything that implements the `PrimaryKey` trait. There are a - `impl<'a> PrimaryKey<'a> for &'a Addr` - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a>> PrimaryKey<'a> for (T, U)` - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a> + Prefixer<'a>, V: PrimaryKey<'a>> PrimaryKey<'a> for (T, U, V)` - - `impl<'a, T: Endian + Clone> PrimaryKey<'a> for IntKey` + - `PrimaryKey` implemented for unsigned integers up to `u64` + - `PrimaryKey` implemented for signed integers up to `i64` That means that byte and string slices, byte vectors, and strings, can be conveniently used as keys. -Moreover, some other types can be used as well, like addresses and address references, pairs and triples, and +Moreover, some other types can be used as well, like addresses and address references, pairs, triples, and integer types. If the key represents an address, we suggest using `&Addr` for keys in storage, instead of `String` or string slices. @@ -211,9 +211,12 @@ legitimate address, and not random text which will fail later. `pub fn addr_validate(&self, &str) -> Addr` in `deps.api` can be used for address validation, and the returned `Addr` can then be conveniently used as key in a `Map` or similar structure. +It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`) +, as that will typically save some cloning during key reading / writing. + ### Composite Keys -There are times when we want to use multiple items as a key, for example, when +There are times when we want to use multiple items as a key. For example, when storing allowances based on account owner and spender. We could try to manually concatenate them before calling, but that can lead to overlap, and is a bit low-level for us. Also, by explicitly separating the keys, we can easily provide @@ -221,12 +224,12 @@ helpers to do range queries over a prefix, such as "show me all allowances for one owner" (first part of the composite key). Just like you'd expect from your favorite database. -Here how we use it with composite keys. Just define a tuple as a key and use that +Here's how we use it with composite keys. Just define a tuple as a key and use that everywhere you used a byte slice above. ```rust -// Note the tuple for primary key. We support one slice, or a 2 or 3-tuple -// adding longer tuples is quite easy but unlikely to be needed. +// Note the tuple for primary key. We support one slice, or a 2 or 3-tuple. +// Adding longer tuples is possible, but unlikely to be needed. const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); fn demo() -> StdResult<()> { @@ -259,7 +262,7 @@ fn demo() -> StdResult<()> { Under the scenes, we create a `Path` from the `Map` when accessing a key. `PEOPLE.load(&store, b"jack") == PEOPLE.key(b"jack").load()`. `Map.key()` returns a `Path`, which has the same interface as `Item`, -reusing the calculated path to this key. +re-using the calculated path to this key. For simple keys, this is just a bit less typing and a bit less gas if you use the same key for many calls. However, for composite keys, like @@ -296,7 +299,7 @@ fn demo() -> StdResult<()> { let empty = john.may_load(&store)?; assert_eq!(None, empty); - // Same for composite keys, just use both parts in key(). + // Same for composite keys, just use both parts in `key()`. // Notice how much less verbose than the above example. let allow = ALLOWANCE.key(("owner", "spender")); allow.save(&mut store, &1234)?; @@ -314,7 +317,7 @@ fn demo() -> StdResult<()> { In addition to getting one particular item out of a map, we can iterate over the map (or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice [`Bound`](#Bound) helpers to easily allow pagination or custom ranges. +and we provide some nice [`Bound`](#Bound) helpers to easily allow pagination, or custom ranges. The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. @@ -323,7 +326,7 @@ over all items with `range(store, min, max, order)`. It supports `Order::Ascendi `min` is the lower bound and `max` is the higher bound. If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to -limit the results to `n` items and start doing pagination. You can also set the `min` bound to +limit the results to `n` items, and start doing pagination. You can also set the `min` bound to eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with `take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any perfect matches. @@ -343,7 +346,7 @@ pub enum Bound<'a, K: PrimaryKey<'a>> { } ``` -To better understand the API, please read the following example: +To better understand the API, please check the following example: ```rust #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -414,15 +417,18 @@ fn demo() -> StdResult<()> { } ``` +*Note*: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#Type-safe bounds over MultiIndex), +below. + ## IndexedMap -Let's use one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. +Let's see one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. ### Definition ```rust pub struct TokenIndexes<'a> { - pub owner: MultiIndex<'a, Addr, TokenInfo>, + pub owner: MultiIndex<'a, Addr, TokenInfo, String>, } impl<'a> IndexList for TokenIndexes<'a> { @@ -453,11 +459,10 @@ pub struct TokenIndexes<'a> { These are the index definitions. Here there's only one index, called `owner`. There could be more, as public members of the `TokenIndexes` struct. - We see that the `owner` index is a `MultiIndex`. A multi-index can have repeated values as keys. The primary key is used internally as the last element of the multi-index key, to disambiguate repeated index values. Like the name implies, this is an index over tokens, by owner. Given that an owner can have multiple tokens, -we need a `MultiIndex` to be able to list / iterate over all the tokens a given owner has. +we need a `MultiIndex` to be able to list / iterate over all the tokens he has. The `TokenInfo` data will originally be stored by `token_id` (which is a string value). You can see this in the token creation code: @@ -472,11 +477,15 @@ You can see this in the token creation code: Given that `token_id` is a string value, we specify `String` as the last argument of the `MultiIndex` definition. That way, the deserialization of the primary key will be done to the right type (an owned string). +*Note*: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of +this last type parameter is crucial, for properly using type-safe bounds. +See [Type-safe bounds over `MultiIndex`](#Type-safe bounds over MultiIndex), below. + Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr`). So that we can list all the tokens an owner has. That's why the `owner` index key is `Addr`. Other important thing here is that the key (and its components, in the case of a composite key) must implement -the `PrimaryKey` trait. You can see that `Addr` do implement `PrimaryKey`: +the `PrimaryKey` trait. You can see that `Addr` do implements `PrimaryKey`: ```rust impl<'a> PrimaryKey<'a> for Addr { @@ -576,17 +585,18 @@ Notice this uses `prefix()`, explained above in the `Map` section. let tokens = res?; ``` Now `tokens` contains `(token_id, TokenInfo)` pairs for the given `owner`. -The pk values are `Vec` in the case of `prefix` + `range`, but will be deserialized to the proper type using -`prefix_de` + `range_de`; provided that the (optional) pk deserialization type (`String`, in this case) -is specified in the `MultiIndex` definition (see #Index keys deserialization, below). +The pk values are `Vec` in the case of `prefix()` + `range_raw()`, but will be deserialized to the proper type using +`prefix()` + `range()`; provided that the pk deserialization type (`String`, in this case) +is correctly specified in the `MultiIndex` definition (see [Index keys deserialization](#Index keys deserialization), +below). -Another example that is similar, but returning only the `token_id`s, using the `keys()` method: +Another example that is similar, but returning only the (raw) `token_id`s, using the `keys_raw()` method: ```rust let pks: Vec<_> = tokens() .idx .owner .prefix(owner_addr) - .keys( + .keys_raw( deps.storage, start, None, @@ -595,13 +605,19 @@ Another example that is similar, but returning only the `token_id`s, using the ` .take(limit) .collect(); ``` -Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. Again, by using `prefix_de` + `range_de`, +Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `prefix()` + `keys`, a deserialized key can be obtained instead, as detailed in the next section. ### Index keys deserialization For `UniqueIndex` and `MultiIndex`, the primary key (`PK`) type needs to be specified, in order to deserialize the primary key to it. This generic type comes with a default of `()`, which means that no deserialization / data -will be provided for the primary key. This is for backwards compatibility with the current `UniqueIndex` / `MultiIndex` -impls. It can also come in handy in cases you don't need the primary key, and are interested only in the deserialized -values. +will be provided for the primary key. This is for backwards compatibility with previous `UniqueIndex` / `MultiIndex` +usages, and will be likely be changed in the future. + +### Type-safe bounds over MultiIndex + +In the particular case of `MultiIndex`, this primary key (`PK`) type also defines the type of the (partial) bounds over +the index key (the part that corresponds to the primary key, that is). +So, to being able to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type +to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. From 4f120539103b15a6c3c4efbb8c36e129e48fb619 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 08:11:15 +0100 Subject: [PATCH 259/631] Fix syntax / links Remove comment about optional PK --- packages/storage-plus/README.md | 35 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 04fa94556..17a439f31 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -104,7 +104,7 @@ we support not only simple binary keys (`&[u8]`), but tuples, which are combined. This allows us to store allowances as composite keys eg. `(owner, spender)` to look up the balance. -Beyond direct lookups, we have a super power not found in Ethereum - +Beyond direct lookups, we have a super-power not found in Ethereum - iteration. That's right, you can list all items in a `Map`, or only part of them. We can efficiently allow pagination over these items as well, starting at the point the last query ended, with low gas costs. @@ -317,7 +317,7 @@ fn demo() -> StdResult<()> { In addition to getting one particular item out of a map, we can iterate over the map (or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice [`Bound`](#Bound) helpers to easily allow pagination, or custom ranges. +and we provide some nice [`Bound`](#bound) helpers to easily allow pagination, or custom ranges. The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. @@ -417,7 +417,7 @@ fn demo() -> StdResult<()> { } ``` -*Note*: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#Type-safe bounds over MultiIndex), +**NB**: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), below. ## IndexedMap @@ -477,9 +477,9 @@ You can see this in the token creation code: Given that `token_id` is a string value, we specify `String` as the last argument of the `MultiIndex` definition. That way, the deserialization of the primary key will be done to the right type (an owned string). -*Note*: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of +**NB**: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of this last type parameter is crucial, for properly using type-safe bounds. -See [Type-safe bounds over `MultiIndex`](#Type-safe bounds over MultiIndex), below. +See [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), below. Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr`). So that we can list all the tokens an owner has. That's why the `owner` index key is `Addr`. @@ -515,7 +515,8 @@ impl<'a> IndexList for TokenIndexes<'a> { ``` This implements the `IndexList` trait for `TokenIndexes`. -Note: this code is more or less boiler-plate, and needed for the internals. Do not try to customize this; + +**NB**: this code is more or less boiler-plate, and needed for the internals. Do not try to customize this; just return a list of all indexes. Implementing this trait serves two purposes (which are really one and the same): it allows the indexes to be queried through `get_indexes`, and, it allows `TokenIndexes` to be treated as an `IndexList`. So that @@ -541,8 +542,7 @@ During index creation, we must supply an index function per index ```rust owner: MultiIndex::new(|d: &TokenInfo| d.owner.clone(), ``` - -, which is the one that will take the value of the original map, and create the index key from it. +which is the one that will take the value of the original map and create the index key from it. Of course, this requires that the elements required for the index key are present in the value. Besides the index function, we must also supply the namespace of the pk, and the one for the new index. @@ -585,9 +585,9 @@ Notice this uses `prefix()`, explained above in the `Map` section. let tokens = res?; ``` Now `tokens` contains `(token_id, TokenInfo)` pairs for the given `owner`. -The pk values are `Vec` in the case of `prefix()` + `range_raw()`, but will be deserialized to the proper type using -`prefix()` + `range()`; provided that the pk deserialization type (`String`, in this case) -is correctly specified in the `MultiIndex` definition (see [Index keys deserialization](#Index keys deserialization), +The pk values are `Vec` in the case of `range_raw()`, but will be deserialized to the proper type using +`range()`; provided that the pk deserialization type (`String`, in this case) is correctly specified +in the `MultiIndex` definition (see [Index keys deserialization](#index-keys-deserialization), below). Another example that is similar, but returning only the (raw) `token_id`s, using the `keys_raw()` method: @@ -605,15 +605,18 @@ Another example that is similar, but returning only the (raw) `token_id`s, using .take(limit) .collect(); ``` -Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `prefix()` + `keys`, -a deserialized key can be obtained instead, as detailed in the next section. +Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `keys` instead, +a deserialized key can be obtained, as detailed in the next section. ### Index keys deserialization For `UniqueIndex` and `MultiIndex`, the primary key (`PK`) type needs to be specified, in order to deserialize -the primary key to it. This generic type comes with a default of `()`, which means that no deserialization / data -will be provided for the primary key. This is for backwards compatibility with previous `UniqueIndex` / `MultiIndex` -usages, and will be likely be changed in the future. +the primary key to it. +This `PK` type specification is also important for `MultiIndex` type-safe bounds, as the primary key +is part of the multi-index key. See next section, [Type-safe bounds over MultiIndex](#type-safe-bounds-over-multiindex). + +**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will if possible +be automated in the future (https://github.com/CosmWasm/cw-plus/issues/531). ### Type-safe bounds over MultiIndex From e4050d87e7866ec3ea8d17d5e3d62345c51d689b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 08:12:56 +0100 Subject: [PATCH 260/631] Remove PK default from MultiIndex --- packages/storage-plus/src/indexes/multi.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index 7cd7b4ebd..f3a4bd70a 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -23,8 +23,11 @@ use std::marker::PhantomData; /// The stored pk_len is used to recover the pk from the index namespace, and perform /// the secondary load of the associated value from the main map. /// -/// The (optional) PK type defines the type of Primary Key deserialization. -pub struct MultiIndex<'a, IK, T, PK = ()> { +/// The PK type defines the type of Primary Key, both for deserialization, and +/// more important, type-safe bound key type. +/// This type must match the encompassing `IndexedMap` primary key type, +/// or its owned variant. +pub struct MultiIndex<'a, IK, T, PK> { index: fn(&T) -> IK, idx_namespace: &'a [u8], // note, we collapse the ik - combining everything under the namespace - and concatenating the pk From 8bae5061c42ba5d145ed37a4bcc0a83de896953b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 08:20:47 +0100 Subject: [PATCH 261/631] Adapt / extend IndexedMap bounds tests over multi-index --- packages/storage-plus/src/indexed_map.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index ee68c7549..9507dec8c 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1391,11 +1391,12 @@ mod test { ); } - mod inclusive_bound { + mod bounds { use super::*; struct Indexes<'a> { - secondary: MultiIndex<'a, u64, u64>, + // The last type param must match the `IndexedMap` primary key type, below + secondary: MultiIndex<'a, u64, u64, &'a str>, } impl<'a> IndexList for Indexes<'a> { @@ -1420,7 +1421,9 @@ mod test { map.save(&mut store, "one", &1).unwrap(); map.save(&mut store, "two", &2).unwrap(); + map.save(&mut store, "three", &3).unwrap(); + // Inclusive prefix-bound let items: Vec<_> = map .idx .secondary @@ -1437,6 +1440,22 @@ mod test { let items: Vec<_> = items.into_iter().map(|(_, v)| v).collect(); assert_eq!(items, vec![1]); + + // Exclusive bound (used for pagination) + // Range over the index specifying a primary key (multi-index key includes the pk) + let items: Vec<_> = map + .idx + .secondary + .range( + &store, + Some(Bound::exclusive((2u64, "two"))), + None, + Order::Ascending, + ) + .collect::>() + .unwrap(); + + assert_eq!(items, vec![("three".to_string(), 3)]); } } } From 0aaf3bd623494ba3f2949c11532e160ddef49b6e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 08:26:03 +0100 Subject: [PATCH 262/631] Add repeated value example in multi-index --- packages/storage-plus/src/indexed_map.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 9507dec8c..ef5d06cc3 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1421,6 +1421,7 @@ mod test { map.save(&mut store, "one", &1).unwrap(); map.save(&mut store, "two", &2).unwrap(); + map.save(&mut store, "two2", &2).unwrap(); map.save(&mut store, "three", &3).unwrap(); // Inclusive prefix-bound @@ -1455,7 +1456,7 @@ mod test { .collect::>() .unwrap(); - assert_eq!(items, vec![("three".to_string(), 3)]); + assert_eq!(items, vec![("two2".to_string(), 2), ("three".to_string(), 3)]); } } } From 01e643f376dfa3934f2929dc99d2956a04a69677 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 08:48:32 +0100 Subject: [PATCH 263/631] Add unique index bounds test for reference / comparison --- packages/storage-plus/src/indexed_map.rs | 59 +++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index ef5d06cc3..1771b0df2 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1391,7 +1391,59 @@ mod test { ); } - mod bounds { + mod bounds_unique_index { + use super::*; + + struct Indexes<'a> { + secondary: UniqueIndex<'a, u64, u64>, + } + + impl<'a> IndexList for Indexes<'a> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.secondary]; + Box::new(v.into_iter()) + } + } + + #[test] + #[cfg(feature = "iterator")] + fn composite_key_query() { + let indexes = Indexes { + secondary: UniqueIndex::new(|secondary| *secondary, "test_map__secondary"), + }; + let map = IndexedMap::<&str, u64, Indexes>::new("test_map", indexes); + let mut store = MockStorage::new(); + + map.save(&mut store, "one", &1).unwrap(); + map.save(&mut store, "two", &2).unwrap(); + map.save(&mut store, "three", &3).unwrap(); + + // Inclusive bound + let items: Vec<_> = map + .idx + .secondary + .range_raw(&store, None, Some(Bound::inclusive(1u64)), Order::Ascending) + .collect::>() + .unwrap(); + + // Strip the index from values (for simpler comparison) + let items: Vec<_> = items.into_iter().map(|(_, v)| v).collect(); + + assert_eq!(items, vec![1]); + + // Exclusive bound + let items: Vec<_> = map + .idx + .secondary + .range(&store, Some(Bound::exclusive(2u64)), None, Order::Ascending) + .collect::>() + .unwrap(); + + assert_eq!(items, vec![((), 3)]); + } + } + + mod bounds_multi_index { use super::*; struct Indexes<'a> { @@ -1456,7 +1508,10 @@ mod test { .collect::>() .unwrap(); - assert_eq!(items, vec![("two2".to_string(), 2), ("three".to_string(), 3)]); + assert_eq!( + items, + vec![("two2".to_string(), 2), ("three".to_string(), 3)] + ); } } } From 135db188b31c750b3620342df9178633c7922afd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 23 Feb 2022 09:04:14 +0100 Subject: [PATCH 264/631] Fix syntax / details --- packages/storage-plus/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 17a439f31..fb1c03b87 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -188,7 +188,7 @@ fn demo() -> StdResult<()> { ### Key types A `Map` key can be anything that implements the `PrimaryKey` trait. There are a series of implementations of -`PrimaryKey` already provided (see [keys.rs](src/keys.rs)): +`PrimaryKey` already provided (see [keys.rs](./src/keys.rs)): - `impl<'a> PrimaryKey<'a> for &'a [u8]` - `impl<'a> PrimaryKey<'a> for &'a str` @@ -211,8 +211,8 @@ legitimate address, and not random text which will fail later. `pub fn addr_validate(&self, &str) -> Addr` in `deps.api` can be used for address validation, and the returned `Addr` can then be conveniently used as key in a `Map` or similar structure. -It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`) -, as that will typically save some cloning during key reading / writing. +It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`), +as that will typically save some cloning during key reading / writing. ### Composite Keys @@ -485,7 +485,7 @@ Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr` an owner has. That's why the `owner` index key is `Addr`. Other important thing here is that the key (and its components, in the case of a composite key) must implement -the `PrimaryKey` trait. You can see that `Addr` do implements `PrimaryKey`: +the `PrimaryKey` trait. You can see that `Addr` does implement `PrimaryKey`: ```rust impl<'a> PrimaryKey<'a> for Addr { @@ -615,12 +615,12 @@ the primary key to it. This `PK` type specification is also important for `MultiIndex` type-safe bounds, as the primary key is part of the multi-index key. See next section, [Type-safe bounds over MultiIndex](#type-safe-bounds-over-multiindex). -**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will if possible +**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will (if possible) be automated in the future (https://github.com/CosmWasm/cw-plus/issues/531). ### Type-safe bounds over MultiIndex -In the particular case of `MultiIndex`, this primary key (`PK`) type also defines the type of the (partial) bounds over +In the particular case of `MultiIndex`, the primary key (`PK`) type parameter also defines the type of the (partial) bounds over the index key (the part that corresponds to the primary key, that is). -So, to being able to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type +So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. From 22c0c213546f0b3e8aa59c8f5c482a58c0b89817 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 24 Feb 2022 21:53:12 +0100 Subject: [PATCH 265/631] Remove useless commas --- packages/storage-plus/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index fb1c03b87..ac07718fd 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -317,7 +317,7 @@ fn demo() -> StdResult<()> { In addition to getting one particular item out of a map, we can iterate over the map (or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice [`Bound`](#bound) helpers to easily allow pagination, or custom ranges. +and we provide some nice [`Bound`](#bound) helpers to easily allow pagination or custom ranges. The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. @@ -326,7 +326,7 @@ over all items with `range(store, min, max, order)`. It supports `Order::Ascendi `min` is the lower bound and `max` is the higher bound. If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to -limit the results to `n` items, and start doing pagination. You can also set the `min` bound to +limit the results to `n` items and start doing pagination. You can also set the `min` bound to eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with `take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any perfect matches. From 88d6bffa542ffe7872f664f5d693b21a0890e406 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 7 Mar 2022 17:04:01 +0100 Subject: [PATCH 266/631] Upgrade cosmwasm to 1.0.0-beta6 --- Cargo.lock | 27 ++++++++++++++++--------- contracts/cw1-subkeys/Cargo.toml | 4 ++-- contracts/cw1-whitelist-ng/Cargo.toml | 4 ++-- contracts/cw1-whitelist/Cargo.toml | 4 ++-- contracts/cw1155-base/Cargo.toml | 4 ++-- contracts/cw20-base/Cargo.toml | 4 ++-- contracts/cw20-ics20/Cargo.toml | 4 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 4 ++-- contracts/cw3-flex-multisig/Cargo.toml | 4 ++-- contracts/cw4-group/Cargo.toml | 4 ++-- contracts/cw4-stake/Cargo.toml | 4 ++-- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 4 ++-- packages/cw1155/Cargo.toml | 4 ++-- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 4 ++-- packages/cw3/Cargo.toml | 4 ++-- packages/cw4/Cargo.toml | 4 ++-- packages/multi-test/Cargo.toml | 4 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 2 +- 21 files changed, 53 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8c4ce5e5..14813c3bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,9 +155,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta5" +version = "1.0.0-beta6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8904127a5b9e325ef5d6b2b3f997dcd74943cd35097139b1a4d15b1b6bccae66" +checksum = "2dddc1443004c6340e55ca66d98e9d2f1a44aadf4ce2bed2c4f29baa8a15e7b7" dependencies = [ "digest", "ed25519-zebra", @@ -168,18 +168,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta5" +version = "1.0.0-beta6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a14364ac4d9d085867929d0cf3e94b1d2100121ce02c33c72961406830002613" +checksum = "fe4f0f10f165b8bcc558a13cddb498140960544519aa0581532c766dd80b5598" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0-beta5" +version = "1.0.0-beta6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2941b87c42620d348e96ed05876bfda0dc1d5454a646d780d32f114c04921d" +checksum = "497432aa9a8e154e3789845f64049d088eb797ba5a7f78da312153f46c822388" dependencies = [ "schemars", "serde_json", @@ -187,13 +187,14 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.0.0-beta5" +version = "1.0.0-beta6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ece12e5bbde434b93937d7b2107e6291f11d69ffa72398c50e8bab41d451d3" +checksum = "2f0f3145097b692b2d95fa5d2c7c6fdd60f193ccc709857e7e1987a608725300" dependencies = [ "base64", "cosmwasm-crypto", "cosmwasm-derive", + "forward_ref", "schemars", "serde", "serde-json-wasm", @@ -203,9 +204,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0-beta5" +version = "1.0.0-beta6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e4338d8e9934effa4594f139ce4e5f4b426796b70e2d53bb7e8605e9adf68c" +checksum = "2945b2c28f64a09e1831f8f830641dc86b39b374c211215e88f2252f474dcb6e" dependencies = [ "cosmwasm-std", "serde", @@ -744,6 +745,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + [[package]] name = "generic-array" version = "0.14.5" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index db313da0a..8ebebea6d 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -23,7 +23,7 @@ cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw1 = { path = "../../packages/cw1", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 89e20e1e9..04732dc59 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -25,7 +25,7 @@ multitest = ["cw-multi-test", "anyhow"] cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw1 = { path = "../../packages/cw1", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -36,6 +36,6 @@ anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index ac7e9ed28..05995e64b 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw1 = { path = "../../packages/cw1", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } +cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index e6197e527..834ac65b2 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw1155 = { path = "../../packages/cw1155", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 03acef104..061e093be 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw20 = { path = "../../packages/cw20", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 2b10d4857..d36fa5d2a 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -21,7 +21,7 @@ library = [] cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw20 = { path = "../../packages/cw20", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5", features = ["stargate"] } +cosmwasm-std = { version = "1.0.0-beta6", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } schemars = "0.8.1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index b1388a00b..089861193 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -22,13 +22,13 @@ cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw3 = { path = "../../packages/cw3", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } cw20 = { path = "../../packages/cw20", version = "0.12.1" } cw20-base = { path = "../cw20-base", version = "0.12.1", features = ["library"] } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index e4f032420..e397f673a 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -24,12 +24,12 @@ cw3 = { path = "../../packages/cw3", version = "0.12.1" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.1", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } cw4-group = { path = "../cw4-group", version = "0.12.1" } cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index b2038f155..842cede30 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -31,10 +31,10 @@ cw2 = { path = "../../packages/cw2", version = "0.12.1" } cw4 = { path = "../../packages/cw4", version = "0.12.1" } cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index a3086f48c..7ed93addc 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -32,10 +32,10 @@ cw4 = { path = "../../packages/cw4", version = "0.12.1" } cw20 = { path = "../../packages/cw20", version = "0.12.1" } cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 17ee89281..4739bb0e9 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } cw-utils = { path = "../utils", version = "0.12.1" } cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } schemars = "0.8.1" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 8b3017c2d..6cac3d9fd 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index e81f36c92..8ae9a6204 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 675d2ecfe..b23fc717d 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta5", default-features = false } +cosmwasm-std = { version = "1.0.0-beta6", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index c24708e85..3d027f622 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 98dcc64af..a643a0f76 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 77c20b649..f61dd94f8 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta5" } +cosmwasm-schema = { version = "1.0.0-beta6" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index f39042c1d..3da22ef5a 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,8 +20,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.12.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1"} -cosmwasm-std = { version = "1.0.0-beta5", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } +cosmwasm-storage = { version = "1.0.0-beta6" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 1e22dd983..1d8d3f0cc 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -18,7 +18,7 @@ iterator = ["cosmwasm-std/iterator"] bench = false [dependencies] -cosmwasm-std = { version = "1.0.0-beta5", default-features = false } +cosmwasm-std = { version = "1.0.0-beta6", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index f2ab10026..82ad9e35a 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } From 45a2776b46ca604b03fd5139b64cca6fa8c7d9c3 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 1 Mar 2022 11:06:01 +0100 Subject: [PATCH 267/631] Adapt code to ContractResult -> SubMsgResult change --- contracts/cw20-ics20/src/ibc.rs | 16 ++++++++-------- .../src/test_helpers/contracts/echo.rs | 6 +++--- packages/multi-test/src/wasm.rs | 10 +++++----- packages/utils/src/parse_reply.rs | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index f666db322..add61ac5f 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -2,10 +2,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{ - attr, entry_point, from_binary, to_binary, BankMsg, Binary, ContractResult, CosmosMsg, Deps, - DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, - IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, - IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, SubMsg, Uint128, WasmMsg, + attr, entry_point, from_binary, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, + IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, + IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, + IbcReceiveResponse, Reply, Response, SubMsg, SubMsgResult, Uint128, WasmMsg, }; use crate::amount::Amount; @@ -87,8 +87,8 @@ const ACK_FAILURE_ID: u64 = 0xfa17; pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> Result { match reply.id { RECEIVE_ID => match reply.result { - ContractResult::Ok(_) => Ok(Response::new()), - ContractResult::Err(err) => { + SubMsgResult::Ok(_) => Ok(Response::new()), + SubMsgResult::Err(err) => { // Important design note: with ibcv2 and wasmd 0.22 we can implement this all much easier. // No reply needed... the receive function and submessage should return error on failure and all // state gets reverted with a proper app-level message auto-generated @@ -113,8 +113,8 @@ pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> Result match reply.result { - ContractResult::Ok(_) => Ok(Response::new()), - ContractResult::Err(err) => Ok(Response::new().set_data(ack_fail(err))), + SubMsgResult::Ok(_) => Ok(Response::new()), + SubMsgResult::Err(err) => Ok(Response::new().set_data(ack_fail(err))), }, _ => Err(ContractError::UnknownReplyId { id: reply.id }), } diff --git a/packages/multi-test/src/test_helpers/contracts/echo.rs b/packages/multi-test/src/test_helpers/contracts/echo.rs index 71737d530..c1d51b3a5 100644 --- a/packages/multi-test/src/test_helpers/contracts/echo.rs +++ b/packages/multi-test/src/test_helpers/contracts/echo.rs @@ -4,8 +4,8 @@ //! Additionally it bypass all events and attributes send to it use cosmwasm_std::{ - to_binary, Attribute, Binary, ContractResult, Deps, DepsMut, Empty, Env, Event, MessageInfo, - Reply, Response, StdError, SubMsg, SubMsgExecutionResponse, + to_binary, Attribute, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Reply, Response, + StdError, SubMsg, SubMsgExecutionResponse, SubMsgResult, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -98,7 +98,7 @@ where if let Reply { id, result: - ContractResult::Ok(SubMsgExecutionResponse { + SubMsgResult::Ok(SubMsgExecutionResponse { data: Some(data), .. }), } = msg diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index ce793c3af..513535230 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -4,9 +4,9 @@ use std::ops::Deref; use cosmwasm_std::{ to_binary, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, - ContractInfoResponse, ContractResult, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, - Order, Querier, QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, - SubMsgExecutionResponse, TransactionInfo, WasmMsg, WasmQuery, + ContractInfoResponse, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, Order, Querier, + QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgExecutionResponse, + SubMsgResult, TransactionInfo, WasmMsg, WasmQuery, }; use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; use prost::Message; @@ -436,7 +436,7 @@ where if matches!(reply_on, ReplyOn::Always | ReplyOn::Success) { let reply = Reply { id, - result: ContractResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgExecutionResponse { events: r.events.clone(), data: r.data, }), @@ -457,7 +457,7 @@ where if matches!(reply_on, ReplyOn::Always | ReplyOn::Error) { let reply = Reply { id, - result: ContractResult::Err(e.to_string()), + result: SubMsgResult::Err(e.to_string()), }; self._reply(api, router, storage, block, contract, reply) } else { diff --git a/packages/utils/src/parse_reply.rs b/packages/utils/src/parse_reply.rs index 37e1a27ca..3b61f7474 100644 --- a/packages/utils/src/parse_reply.rs +++ b/packages/utils/src/parse_reply.rs @@ -168,7 +168,7 @@ pub enum ParseReplyError { mod test { use super::*; use crate::parse_reply::ParseReplyError::{BrokenUtf8, ParseFailure}; - use cosmwasm_std::{ContractResult, SubMsgExecutionResponse}; + use cosmwasm_std::{SubMsgExecutionResponse, SubMsgResult}; use prost::Message; use std::str::from_utf8; @@ -466,7 +466,7 @@ mod test { // Build reply message let msg = Reply { id: 1, - result: ContractResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgExecutionResponse { events: vec![], data: Some(encoded_instantiate_reply.into()), }), @@ -514,7 +514,7 @@ mod test { // Build reply message let msg = Reply { id: 1, - result: ContractResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgExecutionResponse { events: vec![], data: Some(encoded_execute_reply.into()), }), From 907cea7604423511406b16462e261b3ce1e6e97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 9 Mar 2022 12:41:14 +0100 Subject: [PATCH 268/631] Cargo.lock update --- Cargo.lock | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14813c3bf..87edbf431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" dependencies = [ "backtrace", ] @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -774,9 +774,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ "cfg-if", "libc", @@ -881,9 +881,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "log" @@ -1046,14 +1046,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core 0.6.3", - "rand_hc", ] [[package]] @@ -1081,16 +1080,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.4", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", + "getrandom 0.2.5", ] [[package]] @@ -1120,9 +1110,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "regex-syntax", ] @@ -1201,9 +1191,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" +checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" [[package]] name = "serde" From bfffaec066f3887bdfff41db9cec70224af96f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 9 Mar 2022 12:41:46 +0100 Subject: [PATCH 269/631] Set version: 0.13.0 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87edbf431..64a8f025b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -378,7 +378,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.12.1" +version = "0.13.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -395,7 +395,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-std", "criterion", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -418,7 +418,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -428,7 +428,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -445,7 +445,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.12.1" +version = "0.13.0" dependencies = [ "anyhow", "assert_matches", @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.12.1" +version = "0.13.0" dependencies = [ "anyhow", "assert_matches", @@ -483,7 +483,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -494,7 +494,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -509,7 +509,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -519,7 +519,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -530,7 +530,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -621,7 +621,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -637,7 +637,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.12.1" +version = "0.13.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 8ebebea6d..666e7af0a 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw1 = { path = "../../packages/cw1", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw1 = { path = "../../packages/cw1", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.0", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.12.1", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 04732dc59..fe81fc847 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.12.1" +version = "0.13.0" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw1 = { path = "../../packages/cw1", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw1 = { path = "../../packages/cw1", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 05995e64b..94ee651dc 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw1 = { path = "../../packages/cw1", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw1 = { path = "../../packages/cw1", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 834ac65b2..36650e506 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.12.1" +version = "0.13.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw1155 = { path = "../../packages/cw1155", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 061e093be..ff894a876 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw20 = { path = "../../packages/cw20", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw20 = { path = "../../packages/cw20", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index d36fa5d2a..187dbf89d 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw20 = { path = "../../packages/cw20", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw20 = { path = "../../packages/cw20", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 089861193..06b2b40eb 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw3 = { path = "../../packages/cw3", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw3 = { path = "../../packages/cw3", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw20 = { path = "../../packages/cw20", version = "0.12.1" } -cw20-base = { path = "../cw20-base", version = "0.12.1", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } +cw20 = { path = "../../packages/cw20", version = "0.13.0" } +cw20-base = { path = "../cw20-base", version = "0.13.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index e397f673a..ea7d9eb21 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw3 = { path = "../../packages/cw3", version = "0.12.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.12.1", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw3 = { path = "../../packages/cw3", version = "0.13.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw4-group = { path = "../cw4-group", version = "0.12.1" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.12.1" } +cw4-group = { path = "../cw4-group", version = "0.13.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 842cede30..7e41d420a 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw4 = { path = "../../packages/cw4", version = "0.12.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw4 = { path = "../../packages/cw4", version = "0.13.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 7ed93addc..70c422e85 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw2 = { path = "../../packages/cw2", version = "0.12.1" } -cw4 = { path = "../../packages/cw4", version = "0.12.1" } -cw20 = { path = "../../packages/cw20", version = "0.12.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw4 = { path = "../../packages/cw4", version = "0.13.0" } +cw20 = { path = "../../packages/cw20", version = "0.13.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 4739bb0e9..28a99ae27 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta6" } -cw-utils = { path = "../utils", version = "0.12.1" } -cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } +cw-utils = { path = "../utils", version = "0.13.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 6cac3d9fd..bf0d428d9 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 8ae9a6204..96ab68f95 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.12.1" +version = "0.13.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index b23fc717d..501b2eba6 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta6", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 3d027f622..383a789cd 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index a643a0f76..6720ae812 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index f61dd94f8..6ad539d43 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.0" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 3da22ef5a..ed91c3c7d 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.12.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1"} +cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0"} cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta6" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 1d8d3f0cc..7d49d877e 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced/experimental storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 82ad9e35a..da0e411f5 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.12.1" +version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.12.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } prost = "0.9" From 320ea83b409c5cd0993a06b4146d6e124e5e666c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 9 Mar 2022 12:47:57 +0100 Subject: [PATCH 270/631] Changelog update for 0.13.0 --- CHANGELOG.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 731c7c808..b6969264f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,26 @@ # Changelog -## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) +## [v0.13.0](https://github.com/CosmWasm/cw-plus/tree/v0.13.0) (2022-03-09) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.1...HEAD) +**Breaking changes:** + +- Fix `MultiIndex` last type param default / docs [\#669](https://github.com/CosmWasm/cw-plus/issues/669) + +**Closed issues:** + +- Querying over composite key [\#664](https://github.com/CosmWasm/cw-plus/issues/664) +- the method `may_load` exists for struct `cw_storage_plus::Map<'static, (std::string::String, Uint256), Uint256>`, but its trait bounds were not satisfied the following trait bounds were not satisfied: `(std::string::String, Uint256): PrimaryKey` [\#663](https://github.com/CosmWasm/cw-plus/issues/663) +- Make `Bound` helpers return `Option` [\#644](https://github.com/CosmWasm/cw-plus/issues/644) + +**Merged pull requests:** + +- Update cosmwasm to 1.0.0-beta6 [\#672](https://github.com/CosmWasm/cw-plus/pull/672) ([webmaster128](https://github.com/webmaster128)) +- Update storage plus docs / Remove `MultiIndex` PK default [\#671](https://github.com/CosmWasm/cw-plus/pull/671) ([maurolacy](https://github.com/maurolacy)) +- fix: Remove old TODO comment in cw3-flex readme [\#661](https://github.com/CosmWasm/cw-plus/pull/661) ([apollo-sturdy](https://github.com/apollo-sturdy)) +- Properly handle generic queries in multi-test [\#660](https://github.com/CosmWasm/cw-plus/pull/660) ([ethanfrey](https://github.com/ethanfrey)) + ## [v0.12.1](https://github.com/CosmWasm/cw-plus/tree/v0.12.1) (2022-02-14) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.0...v0.12.1) From ce4aeda0e5516a4dd1e4741a4b11db61e30bec6a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 9 Mar 2022 13:39:29 +0100 Subject: [PATCH 271/631] Fix v0.13.0 changelog entry --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6969264f..ff503d3f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Changelog +## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.0...HEAD) + ## [v0.13.0](https://github.com/CosmWasm/cw-plus/tree/v0.13.0) (2022-03-09) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.1...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.12.1...0.13.0) **Breaking changes:** From 44f65e674c780c2b61a1ab529db69a7e8d8f4da5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 9 Mar 2022 15:17:12 +0100 Subject: [PATCH 272/631] Add "add upcoming entry" option to update_changelog --- scripts/update_changelog.sh | 38 +++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/scripts/update_changelog.sh b/scripts/update_changelog.sh index 6b2900615..36fe6cbc8 100755 --- a/scripts/update_changelog.sh +++ b/scripts/update_changelog.sh @@ -1,19 +1,28 @@ #!/bin/bash - +set -o errexit -o pipefail ORIGINAL_OPTS=$* -OPTS=$(getopt -l "help,since-tag:,full,token:" -o "hft" -- "$@") || exit 1 +OPTS=$(getopt -l "help,since-tag:,upcoming-tag:,full,token:" -o "hu:ft" -- "$@") || exit 1 + +function print_usage() { + echo -e "Usage: $0 [-h|--help] [-f|--full] [--since-tag ] [-u|--upcoming-tag] [-t|--token ] +-h, --help Display help +-f, --full Process changes since the beginning (by default: since latest git version tag) +--since-tag Process changes since git version tag (by default: since latest git version tag) +-u, --upcoming-tag Add a title in CHANGELOG for the new changes +--token Pass changelog github token " +} + +function remove_opt() { + ORIGINAL_OPTS=$(echo "$ORIGINAL_OPTS" | sed "s/\\B$1\\b//") +} eval set -- "$OPTS" while true do case $1 in -h|--help) - echo -e "Usage: $0 [-h|--help] [-f|--full] [--since-tag ] [-t|--token ] --h, --help Display help --f, --full Process changes since the beginning (by default: since latest git version tag) ---since-tag Process changes since git version tag (by default: since latest git version tag) ---token Pass changelog github token " + print_usage exit 0 ;; --since-tag) @@ -22,7 +31,13 @@ case $1 in ;; -f|--full) TAG="" - ORIGINAL_OPTS=$(echo "$ORIGINAL_OPTS" | sed "s/\\B$1\\b//") + remove_opt $1 + ;; + -u|--upcoming-tag) + remove_opt $1 + shift + UPCOMING_TAG="$1" + remove_opt $1 ;; --) shift @@ -50,4 +65,11 @@ sed -i -n "/^## \\[${TAG}[^]]*\\]/,\$p" CHANGELOG.md github_changelog_generator -u CosmWasm -p cw-plus --base CHANGELOG.md $ORIGINAL_OPTS || cp /tmp/CHANGELOG.md.$$ CHANGELOG.md +if [ -n "$UPCOMING_TAG" ] +then + # Add "upcoming" version tag + TODAY=$(date "+%Y-%m-%d") + sed -i "s+\[Full Changelog\](https://github.com/CosmWasm/cw-plus/compare/\(.*\)\.\.\.HEAD)+[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/$UPCOMING_TAG...HEAD)\n\n## [$UPCOMING_TAG](https://github.com/CosmWasm/cw-plus/tree/$UPCOMING_TAG) ($TODAY)\n\n[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/\1...$UPCOMING_TAG)+" CHANGELOG.md +fi + rm -f /tmp/CHANGELOG.md.$$ From 592e3154242cdef1870b1d201a294689a40a77c1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 9 Mar 2022 15:19:06 +0100 Subject: [PATCH 273/631] Add --help for set_version --- scripts/set_version.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/set_version.sh b/scripts/set_version.sh index 26987c1ff..019b8125d 100755 --- a/scripts/set_version.sh +++ b/scripts/set_version.sh @@ -1,14 +1,14 @@ #!/bin/bash set -o errexit -o nounset -o pipefail -command -v shellcheck > /dev/null && shellcheck "$0" +command -v shellcheck >/dev/null && shellcheck "$0" function print_usage() { - echo "Usage: $0 NEW_VERSION" - echo "" - echo "e.g. $0 0.8.0" + echo "Usage: $0 [-h|--help] " + echo "e.g.: $0 0.8.0" } -if [ "$#" -ne 1 ]; then +if [ "$#" -ne 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] +then print_usage exit 1 fi From 160fb06697f91162bbdeea5861357a297296facd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 9 Mar 2022 15:21:21 +0100 Subject: [PATCH 274/631] Add --help to publish.sh --- scripts/publish.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 8c4bee118..afd4c696b 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -1,6 +1,17 @@ #!/bin/bash set -o errexit -o nounset -o pipefail -command -v shellcheck > /dev/null && shellcheck "$0" +command -v shellcheck >/dev/null && shellcheck "$0" + +function print_usage() { + echo "Usage: $0 [-h|--help]" + echo "Publishes crates to crates.io." +} + +if [ "$1" = "-h" ] || [ "$1" = "--help" ] +then + print_usage + exit 1 +fi # this should really more to cosmwasm... STORAGE_PACKAGES="storage-plus" From 99d06a65a461da76bac2c626315f81dd36e8078e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 9 Mar 2022 20:13:11 +0100 Subject: [PATCH 275/631] Clarify the stability of cw-storage-plus, no longer Experimental --- packages/storage-plus/Cargo.toml | 2 +- packages/storage-plus/README.md | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 7d49d877e..6032e7384 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -3,7 +3,7 @@ name = "cw-storage-plus" version = "0.13.0" authors = ["Ethan Frey "] edition = "2018" -description = "Enhanced/experimental storage engines" +description = "Enhanced storage engines" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index ac07718fd..2b1e53c0e 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -1,14 +1,25 @@ -# CW-Storage-Plus: Enhanced/experimental storage engines for CosmWasm +# CW-Storage-Plus: Enhanced storage engines for CosmWasm -The ideas in here are based on the `cosmwasm-storage` crate. However, -after much usage, we decided a complete rewrite could allow us to add -more powerful and easy to use interfaces. Here are those interfaces. +After building `cosmwasm-storage`, we realized many of the design decisions were +limiting us and producing a lot of needless boilerplate. The decision was made to leave +those APIs stable for anyone wanting a very basic abstraction on the KV-store and to +build a much more powerful and complex ORM layer that can provide powerful accessors +using complex key types, which are transparently turned into bytes. + +This led to a number of breaking API changes in this package of the course of several +releases as we updated this with lots of experience, user feedback, and deep dives to harness +the full power of generics. **Status: beta** -This has been heavily used in many production-quality contracts and -heavily refined. The code has demonstrated itself to be stable and powerful. -Please feel free to use it in your contracts. +As of `cw-storage-plus` `v0.12` the API should be quite stable. +There are no major API breaking issues pending, and all API changes will be documented +in [`MIGRATING.md`](../../MIGRATING.md). + +This has been heavily used in many production-quality contracts. +The code has demonstrated itself to be stable and powerful. +It has not been audited, and Confio assumes no liability, butwe consider it mature enough +to be the standard storage layer for your contracts. ## Usage Overview From c7acbb573bc911b2673ebfc066847bd05c686fed Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 10 Mar 2022 13:08:44 +0100 Subject: [PATCH 276/631] Update packages/storage-plus/README.md Co-authored-by: Jakub Bogucki --- packages/storage-plus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 2b1e53c0e..56c5b0f16 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -18,7 +18,7 @@ in [`MIGRATING.md`](../../MIGRATING.md). This has been heavily used in many production-quality contracts. The code has demonstrated itself to be stable and powerful. -It has not been audited, and Confio assumes no liability, butwe consider it mature enough +It has not been audited, and Confio assumes no liability, but we consider it mature enough to be the standard storage layer for your contracts. ## Usage Overview From bd110774cc182105e8ec6a8f83f04677059a1cc3 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 10 Mar 2022 13:08:50 +0100 Subject: [PATCH 277/631] Update packages/storage-plus/README.md Co-authored-by: Mauro Lacy --- packages/storage-plus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 56c5b0f16..3e2691df1 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -19,7 +19,7 @@ in [`MIGRATING.md`](../../MIGRATING.md). This has been heavily used in many production-quality contracts. The code has demonstrated itself to be stable and powerful. It has not been audited, and Confio assumes no liability, but we consider it mature enough -to be the standard storage layer for your contracts. +to be the **standard storage layer** for your contracts. ## Usage Overview From af19599fa38760431ffbbcfb43e8399d842415c9 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 13:15:46 +0100 Subject: [PATCH 278/631] Remove extra "v" field, act is if always set --- contracts/cw20-ics20/src/ibc.rs | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index add61ac5f..d46121f65 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -11,8 +11,8 @@ use cosmwasm_std::{ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ - increase_channel_balance, reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, - ReplyArgs, ALLOW_LIST, CHANNEL_INFO, REPLY_ARGS, + reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, + CHANNEL_INFO, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -32,12 +32,8 @@ pub struct Ics20Packet { pub receiver: String, /// the sender address pub sender: String, - /// used only by us to control ack handling - pub v: Option, } -const V2: u32 = 2; - impl Ics20Packet { pub fn new>(amount: Uint128, denom: T, sender: &str, receiver: &str) -> Self { Ics20Packet { @@ -45,7 +41,6 @@ impl Ics20Packet { amount, sender: sender.to_string(), receiver: receiver.to_string(), - v: Some(V2), } } @@ -317,15 +312,9 @@ pub fn ibc_packet_timeout( } // update the balance stored on this (channel, denom) index -fn on_packet_success(deps: DepsMut, packet: IbcPacket) -> Result { +fn on_packet_success(_deps: DepsMut, packet: IbcPacket) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; - // if this was for an older (pre-v2) packet we send continue with old behavior - // (this is needed for transitioning on a system with pending packet) - if msg.v.is_none() { - increase_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; - } - // similar event messages like ibctransfer module let attributes = vec![ attr("action", "acknowledge"), @@ -347,10 +336,8 @@ fn on_packet_failure( ) -> Result { let msg: Ics20Packet = from_binary(&packet.data)?; - // undo the balance update (but not for pre-v2/None packets which didn't add before sending) - if msg.v.is_some() { - reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; - } + // undo the balance update on failure (as we pre-emptively added it on send) + reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; let to_send = Amount::from_parts(msg.denom.clone(), msg.amount); let gas_limit = check_gas_limit(deps.as_ref(), &to_send)?; @@ -426,7 +413,7 @@ mod test { "wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc", ); // Example message generated from the SDK - let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n","v":2}"#; + let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n"}"#; let encdoded = String::from_utf8(to_vec(&packet).unwrap()).unwrap(); assert_eq!(expected, encdoded.as_str()); @@ -474,7 +461,6 @@ mod test { amount: amount.into(), sender: "remote-sender".to_string(), receiver: receiver.to_string(), - v: Some(V2), }; print!("Packet denom: {}", &data.denom); IbcPacket::new( @@ -535,7 +521,6 @@ mod test { amount: Uint128::new(987654321), sender: "local-sender".to_string(), receiver: "remote-rcpt".to_string(), - v: Some(V2), }; let timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); assert_eq!( From 2aa334ab20d080135b09c0e4837d35b2e1ed4e01 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 13:34:07 +0100 Subject: [PATCH 279/631] Add new migration path for old contracts to the new logic --- contracts/cw20-ics20/src/contract.rs | 9 ++++-- contracts/cw20-ics20/src/migrations.rs | 40 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 706a16073..e04f4eb6e 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -13,7 +13,7 @@ use cw_storage_plus::Bound; use crate::amount::Amount; use crate::error::ContractError; use crate::ibc::Ics20Packet; -use crate::migrations::v1; +use crate::migrations::{v1, v2}; use crate::msg::{ AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, ListAllowedResponse, ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, TransferMsg, @@ -199,9 +199,10 @@ pub fn execute_allow( const MIGRATE_MIN_VERSION: &str = "0.11.1"; const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; +const MIGRATE_VERSION_3: &str = "0.13.1"; #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { +pub fn migrate(mut deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result { let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; let stored = get_contract_version(deps.storage)?; let storage_version: Version = stored.version.parse().map_err(from_semver)?; @@ -235,6 +236,10 @@ pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Resultv3 converstion if we are v2 style + if storage_version <= MIGRATE_VERSION_3.parse().map_err(from_semver)? { + v2::update_balances(deps.branch(), &env)?; + } // otherwise no migration (yet) - add them here // we don't need to save anything if migrating from the same version diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index e874569a0..4c79b6ffb 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -14,3 +14,43 @@ pub mod v1 { pub const CONFIG: Item = Item::new("ics20_config"); } + +// v2 format is anything older than 0.13.1 when we only updated the internal balances on success ack +pub mod v2 { + use crate::state::{CHANNEL_INFO, CHANNEL_STATE}; + use crate::ContractError; + use cosmwasm_std::{Coin, DepsMut, Env, Order, StdResult}; + + pub fn update_balances(deps: DepsMut, env: &Env) -> Result<(), ContractError> { + let channels = CHANNEL_INFO + .keys(deps.storage, None, None, Order::Ascending) + .collect::>>()?; + match channels.len() { + 0 => Ok(()), + 1 => { + let channel = &channels[0]; + let addr = &env.contract.address; + let states = CHANNEL_STATE + .prefix(channel) + .range(deps.storage, None, None, Order::Ascending) + .collect::>>()?; + for (denom, mut state) in states.into_iter() { + // this checks if we have received some coins that are "in flight" and not yet accounted in the state + let Coin { amount, .. } = deps.querier.query_balance(addr, &denom)?; + let diff = state.outstanding - amount; + // if they are in flight, we add them to the internal state now, as if we added them when sent (not when acked) + // to match the current logic + if !diff.is_zero() { + state.outstanding += diff; + state.total_sent += diff; + CHANNEL_STATE.save(deps.storage, (channel, &denom), &state)?; + } + } + Ok(()) + } + _ => Err(ContractError::CannotMigrate { + previous_contract: "multiple channels open".into(), + }), + } + } +} From 1b43accd2970aa0aac08d71c7d0df0316a45454e Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 24 Mar 2022 15:15:44 +0000 Subject: [PATCH 280/631] Address feedback --- contracts/cw3-fixed-multisig/src/contract.rs | 40 +++++- contracts/cw3-fixed-multisig/src/state.rs | 137 +++++++++++-------- 2 files changed, 118 insertions(+), 59 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index f55609bfe..629544bda 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -788,7 +788,7 @@ mod tests { proposal_id, vote: Vote::No, }; - // Voter1 vote no + // Voter1 vote no, weight 1 let info = mock_info(VOTER1, &[]); let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); @@ -802,16 +802,50 @@ mod tests { .add_attribute("status", "Open") ); + // Voter 4 votes no, weight 4, total weight for no so far 5, need 14 to reject let info = mock_info(VOTER4, &[]); - let res = execute(deps.as_mut(), mock_env(), info, no_vote).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); - // Verify it is now rejected due to reaching threshold + // Verify it is still open as we actually need no votes > 16 - 3 assert_eq!( res, Response::new() .add_attribute("action", "vote") .add_attribute("sender", VOTER4) .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Open") + ); + + // Voter 3 votes no, weight 3, total weight for no far 8, need 14 + let info = mock_info(VOTER3, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); + + // Voter 5 votes no, weight 5, total weight for no far 13, need 14 + let info = mock_info(VOTER5, &[]); + let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); + + // Verify it is still open as we actually need no votes > 16 - 3 + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER5) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Open") + ); + + // Voter 2 votes no, weight 2, total weight for no so far 15, need 14. + // Can now reject + let info = mock_info(VOTER2, &[]); + let res = execute(deps.as_mut(), mock_env(), info, no_vote).unwrap(); + + // Verify it is rejected as, 15 no votes > 16 - 3 + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER2) + .add_attribute("proposal_id", proposal_id.to_string()) .add_attribute("status", "Rejected") ); } diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 361187dc4..e1ea12ef8 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -57,23 +57,17 @@ impl Proposal { self.status = self.current_status(block); } - /// Helper function to check if a certain vote count has reached threshold. - /// Only called from is_rejected and is_passed for no and yes votes - /// Handles the different threshold types accordingly. - /// This function returns true if and only if vote_count is greater than the threshold which - /// is calculated. - /// In the case where we use yes votes, this function will return true if the proposal will pass. - /// In the case where we use no votes, this function will return true if the - /// proposal will be rejected regardless of other votes. - fn does_vote_count_reach_threshold(&self, vote_count: u64, block: &BlockInfo) -> bool { + /// Returns true if this proposal is sure to pass (even before expiration, if no future + /// sequence of possible votes could cause it to fail). + pub fn is_passed(&self, block: &BlockInfo) -> bool { match self.threshold { Threshold::AbsoluteCount { weight: weight_needed, - } => vote_count >= weight_needed, + } => self.votes.yes >= weight_needed, Threshold::AbsolutePercentage { percentage: percentage_needed, } => { - vote_count + self.votes.yes >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) } Threshold::ThresholdQuorum { threshold, quorum } => { @@ -84,27 +78,53 @@ impl Proposal { if self.expires.is_expired(block) { // If expired, we compare vote_count against the total number of votes (minus abstain). let opinions = self.votes.total() - self.votes.abstain; - vote_count >= votes_needed(opinions, threshold) + self.votes.yes >= votes_needed(opinions, threshold) } else { // If not expired, we must assume all non-votes will be cast against // vote_count let possible_opinions = self.total_weight - self.votes.abstain; - vote_count >= votes_needed(possible_opinions, threshold) + self.votes.yes >= votes_needed(possible_opinions, threshold) } } } } - /// Returns true if this proposal is sure to pass (even before expiration, if no future - /// sequence of possible votes could cause it to fail). - pub fn is_passed(&self, block: &BlockInfo) -> bool { - self.does_vote_count_reach_threshold(self.votes.yes, block) - } - /// Returns true if this proposal is sure to be rejected (even before expiration, if /// no future sequence of possible votes could cause it to fail). pub fn is_rejected(&self, block: &BlockInfo) -> bool { - self.does_vote_count_reach_threshold(self.votes.no, block) + match self.threshold { + Threshold::AbsoluteCount { + weight: weight_needed, + } => { + let weight = self.total_weight - weight_needed; + self.votes.no > weight + } + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => { + self.votes.no + >= votes_needed( + self.total_weight - self.votes.abstain, + Decimal::one() - percentage_needed, + ) + } + Threshold::ThresholdQuorum { threshold, quorum } => { + // we always require the quorum + if self.votes.total() < votes_needed(self.total_weight, quorum) { + return false; + } + if self.expires.is_expired(block) { + // If expired, we compare vote_count against the total number of votes (minus abstain). + let opinions = self.votes.total() - self.votes.abstain; + self.votes.no >= votes_needed(opinions, Decimal::one() - threshold) + } else { + // If not expired, we must assume all non-votes will be cast against + // vote_count + let possible_opinions = self.total_weight - self.votes.abstain; + self.votes.no >= votes_needed(possible_opinions, Decimal::one() - threshold) + } + } + } } } @@ -276,11 +296,11 @@ mod test { let mut votes = Votes::yes(0); votes.add_vote(Vote::Veto, 4); votes.add_vote(Vote::No, 7); - // same expired or not, total_weight or whatever + // In order to reject the proposal we need no votes > 30 - 10, currently it is not rejected assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, false)); assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, true)); - // a few more no votes and we have rejected the prop - votes.add_vote(Vote::No, 3); + // 7 + 14 = 21 > 20, we can now reject + votes.add_vote(Vote::No, 14); assert!(check_is_rejected(fixed.clone(), votes.clone(), 30, false)); assert!(check_is_rejected(fixed, votes, 30, true)); } @@ -308,7 +328,7 @@ mod test { #[test] fn proposal_rejected_absolute_percentage() { let percent = Threshold::AbsolutePercentage { - percentage: Decimal::percent(50), + percentage: Decimal::percent(60), }; // 4 YES, 7 NO, 2 ABSTAIN @@ -317,24 +337,25 @@ mod test { votes.add_vote(Vote::Abstain, 2); // 15 total voting power - // 7 / (15 - 2) > 50% - // Expiry does not matter + // we need no votes > 0.4 * 15, no votes > 6 assert!(check_is_rejected(percent.clone(), votes.clone(), 15, false)); assert!(check_is_rejected(percent.clone(), votes.clone(), 15, true)); // 17 total voting power - // 7 / (17 - 2) < 50% + // we need no votes > 0.4 * 17, no votes > 6.8 + // still rejected + assert!(check_is_rejected(percent.clone(), votes.clone(), 17, false)); + assert!(check_is_rejected(percent.clone(), votes.clone(), 17, true)); + + // Not rejected if total weight is 20 + // as no votes > 0.4 * 18, no votes > 8 assert!(!check_is_rejected( percent.clone(), votes.clone(), - 17, + 20, false )); - assert!(!check_is_rejected(percent.clone(), votes.clone(), 17, true)); - - // Rejected if total was lower - assert!(check_is_rejected(percent.clone(), votes.clone(), 14, false)); - assert!(check_is_rejected(percent, votes.clone(), 14, true)); + assert!(!check_is_rejected(percent, votes.clone(), 20, true)); } #[test] @@ -407,7 +428,7 @@ mod test { #[test] fn proposal_rejected_quorum() { let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(50), + threshold: Decimal::percent(60), quorum: Decimal::percent(40), }; // all non-yes votes are counted for quorum @@ -427,13 +448,16 @@ mod test { // fails any way you look at it let failing = Votes { yes: 5, - no: 6, + no: 5, abstain: 2, - veto: 2, + veto: 3, }; // first, expired (voting period over) - // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) + // over quorum (40% of 30 = 12, 13 votes casted) + // 13 - 2 abstains = 11 + // we need no votes > 0.4 * 11, no votes > 4.4 + // We can reject this assert!(check_is_rejected( quorum.clone(), rejecting.clone(), @@ -441,16 +465,19 @@ mod test { true )); // Under quorum means it cannot be rejected + // (40% of 50 = 20), 13 votes casted assert!(!check_is_rejected( quorum.clone(), rejecting.clone(), - 33, + 50, true )); // over quorum, threshold passes if we ignore abstain - // 17 total votes w/ abstain => 40% quorum of 40 total - // 6 no / (6 no + 4 yes + 2 votes) => 50% threshold + // 17 total votes > 40% quorum + // 6 no > 0.4 * (6 no + 4 yes + 2 votes) + // 6 > 4.8 + // we can reject assert!(check_is_rejected( quorum.clone(), rejected_ignoring_abstain.clone(), @@ -458,24 +485,16 @@ mod test { true )); - // over quorum, but under threshold fails also + // over quorum + // total opinions due to abstains: 13 + // no votes > 0.4 * 13, no votes > 5 to reject, we have 5 exactly so cannot reject assert!(!check_is_rejected(quorum.clone(), failing, 20, true)); - // Voting is still open so assume rest of votes are yes - // threshold not reached - assert!(!check_is_rejected( - quorum.clone(), - rejecting.clone(), - 30, - false - )); - assert!(!check_is_rejected( - quorum.clone(), - rejected_ignoring_abstain.clone(), - 40, - false - )); - // if we have threshold * total_weight as no votes this must reject + // voting period on going + // over quorum (40% of 14 = 5, 13 votes casted) + // 13 - 2 abstains = 11 + // we need no votes > 0.4 * 11, no votes > 4.4 + // We can reject this even when it hasn't expired assert!(check_is_rejected( quorum.clone(), rejecting.clone(), @@ -483,12 +502,18 @@ mod test { false )); // all votes have been cast, some abstain + // voting period on going + // over quorum (40% of 17 = 7, 17 casted_ + // 17 - 5 = 12 total opinions + // we need no votes > 0.4 * 12, no votes > 4.8 + // We can reject this even when it hasn't expired assert!(check_is_rejected( quorum.clone(), rejected_ignoring_abstain, 17, false )); + // 3 votes uncast, if they all vote yes, we have 7 no, 7 yes+veto, 2 abstain (out of 16) assert!(check_is_rejected(quorum, rejecting, 16, false)); } From 3b326ee4dfd0ef55a0e8322a63c5193080666039 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 24 Mar 2022 15:23:36 +0000 Subject: [PATCH 281/631] Correct small error --- contracts/cw3-fixed-multisig/src/state.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index fbb2cb990..3d558c8d2 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -116,12 +116,12 @@ impl Proposal { if self.expires.is_expired(block) { // If expired, we compare vote_count against the total number of votes (minus abstain). let opinions = self.votes.total() - self.votes.abstain; - self.votes.no >= votes_needed(opinions, Decimal::one() - threshold) + self.votes.no > votes_needed(opinions, Decimal::one() - threshold) } else { // If not expired, we must assume all non-votes will be cast against // vote_count let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.no >= votes_needed(possible_opinions, Decimal::one() - threshold) + self.votes.no > votes_needed(possible_opinions, Decimal::one() - threshold) } } } From 514a203d5a28136fb32074715c530c0172bd1859 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 17:44:44 +0100 Subject: [PATCH 282/631] Test migration --- contracts/cw20-ics20/src/contract.rs | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index e04f4eb6e..3c8b25aa9 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -365,9 +365,10 @@ mod test { use super::*; use crate::test_helpers::*; - use cosmwasm_std::testing::{mock_env, mock_info}; + use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{coin, coins, CosmosMsg, IbcMsg, StdError, Uint128}; + use crate::state::ChannelState; use cw_utils::PaymentError; #[test] @@ -532,4 +533,36 @@ mod test { let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::NotOnAllowList); } + + #[test] + fn v3_migration_works() { + // basic state with one channel + let send_channel = "channel-15"; + let cw20_addr = "my-token"; + let native = "ucosm"; + let mut deps = setup(&[send_channel], &[(cw20_addr, 123456)]); + + // mock that we sent some tokens in both native and cw20 (TODO: cw20) + // balances set high + deps.querier + .update_balance(MOCK_CONTRACT_ADDR, coins(50000, native)); + + // channel state a bit lower (some in-flight acks) + let state = ChannelState { + // 14000 not accounted for (in-flight) + outstanding: Uint128::new(36000), + total_sent: Uint128::new(100000), + }; + CHANNEL_STATE + .save(deps.as_mut().storage, (send_channel, native), &state) + .unwrap(); + + // run migration + migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + + // check new channel state + let chan = query_channel(deps.as_ref(), send_channel.into()).unwrap(); + assert_eq!(chan.balances, vec![Amount::native(50000, native)]); + assert_eq!(chan.total_sent, vec![Amount::native(114000, native)]); + } } From f0c32d32febdb3b50ed0de13dbf88806e87dae30 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 17:45:25 +0100 Subject: [PATCH 283/631] Fix subtration in diff --- contracts/cw20-ics20/src/migrations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index 4c79b6ffb..c48e7f71a 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -37,7 +37,7 @@ pub mod v2 { for (denom, mut state) in states.into_iter() { // this checks if we have received some coins that are "in flight" and not yet accounted in the state let Coin { amount, .. } = deps.querier.query_balance(addr, &denom)?; - let diff = state.outstanding - amount; + let diff = amount - state.outstanding; // if they are in flight, we add them to the internal state now, as if we added them when sent (not when acked) // to match the current logic if !diff.is_zero() { From 7689360a721eb6e762ced7d77076333872378e48 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 24 Mar 2022 17:04:08 +0000 Subject: [PATCH 284/631] Typo again --- contracts/cw3-fixed-multisig/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 3d558c8d2..039fbe17f 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -103,7 +103,7 @@ impl Proposal { percentage: percentage_needed, } => { self.votes.no - >= votes_needed( + > votes_needed( self.total_weight - self.votes.abstain, Decimal::one() - percentage_needed, ) From 9ad5fef463ad7ff4ffd187e1b23ec2c03e0758ef Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 18:09:40 +0100 Subject: [PATCH 285/631] Add (untested) support for migrating cw20 --- contracts/cw20-ics20/src/migrations.rs | 61 ++++++++++++++++++++------ 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index c48e7f71a..536b4da96 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -17,11 +17,13 @@ pub mod v1 { // v2 format is anything older than 0.13.1 when we only updated the internal balances on success ack pub mod v2 { - use crate::state::{CHANNEL_INFO, CHANNEL_STATE}; + use crate::amount::Amount; + use crate::state::{ChannelState, CHANNEL_INFO, CHANNEL_STATE}; use crate::ContractError; - use cosmwasm_std::{Coin, DepsMut, Env, Order, StdResult}; + use cosmwasm_std::{to_binary, Addr, DepsMut, Env, Order, StdResult, WasmQuery}; + use cw20::{BalanceResponse, Cw20QueryMsg}; - pub fn update_balances(deps: DepsMut, env: &Env) -> Result<(), ContractError> { + pub fn update_balances(mut deps: DepsMut, env: &Env) -> Result<(), ContractError> { let channels = CHANNEL_INFO .keys(deps.storage, None, None, Order::Ascending) .collect::>>()?; @@ -34,17 +36,8 @@ pub mod v2 { .prefix(channel) .range(deps.storage, None, None, Order::Ascending) .collect::>>()?; - for (denom, mut state) in states.into_iter() { - // this checks if we have received some coins that are "in flight" and not yet accounted in the state - let Coin { amount, .. } = deps.querier.query_balance(addr, &denom)?; - let diff = amount - state.outstanding; - // if they are in flight, we add them to the internal state now, as if we added them when sent (not when acked) - // to match the current logic - if !diff.is_zero() { - state.outstanding += diff; - state.total_sent += diff; - CHANNEL_STATE.save(deps.storage, (channel, &denom), &state)?; - } + for (denom, state) in states.into_iter() { + update_denom(deps.branch(), addr, channel, denom, state)?; } Ok(()) } @@ -53,4 +46,44 @@ pub mod v2 { }), } } + + fn update_denom( + deps: DepsMut, + contract: &Addr, + channel: &str, + denom: String, + mut state: ChannelState, + ) -> StdResult<()> { + // handle this for both native and cw20 + let balance = match Amount::from_parts(denom.clone(), state.outstanding) { + Amount::Native(coin) => deps.querier.query_balance(contract, coin.denom)?.amount, + Amount::Cw20(coin) => { + // FIXME: we should be able to do this with the following line, but QuerierWrapper doesn't play + // with the Querier generics + // Cw20Contract(contract.clone()).balance(&deps.querier, contract)? + let msg = Cw20QueryMsg::Balance { + address: contract.into(), + }; + let query = WasmQuery::Smart { + contract_addr: coin.address, + msg: to_binary(&msg)?, + } + .into(); + let res: BalanceResponse = deps.querier.query(&query)?; + res.balance + } + }; + + // this checks if we have received some coins that are "in flight" and not yet accounted in the state + let diff = balance - state.outstanding; + // if they are in flight, we add them to the internal state now, as if we added them when sent (not when acked) + // to match the current logic + if !diff.is_zero() { + state.outstanding += diff; + state.total_sent += diff; + CHANNEL_STATE.save(deps.storage, (channel, &denom), &state)?; + } + + Ok(()) + } } From 068d33fcc0d1461c73ea7573e8c81aed4d355470 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 24 Mar 2022 17:29:13 +0000 Subject: [PATCH 286/631] Address feedback --- contracts/cw3-fixed-multisig/src/state.rs | 42 +++++++++++++++++------ 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 039fbe17f..eedf1c46e 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -81,7 +81,6 @@ impl Proposal { self.votes.yes >= votes_needed(opinions, threshold) } else { // If not expired, we must assume all non-votes will be cast against - // vote_count let possible_opinions = self.total_weight - self.votes.abstain; self.votes.yes >= votes_needed(possible_opinions, threshold) } @@ -108,18 +107,16 @@ impl Proposal { Decimal::one() - percentage_needed, ) } - Threshold::ThresholdQuorum { threshold, quorum } => { - // we always require the quorum - if self.votes.total() < votes_needed(self.total_weight, quorum) { - return false; - } + Threshold::ThresholdQuorum { + threshold, + quorum: _, + } => { if self.expires.is_expired(block) { // If expired, we compare vote_count against the total number of votes (minus abstain). let opinions = self.votes.total() - self.votes.abstain; self.votes.no > votes_needed(opinions, Decimal::one() - threshold) } else { - // If not expired, we must assume all non-votes will be cast against - // vote_count + // If not expired, we must assume all non-votes will be cast for let possible_opinions = self.total_weight - self.votes.abstain; self.votes.no > votes_needed(possible_opinions, Decimal::one() - threshold) } @@ -464,12 +461,37 @@ mod test { 30, true )); - // Under quorum means it cannot be rejected - // (40% of 50 = 20), 13 votes casted + + // Under quorum and cannot reject as it is not expired assert!(!check_is_rejected( quorum.clone(), rejecting.clone(), 50, + false + )); + // Can reject when expired + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 50, + true + )); + + // Check edgecase where quorum is not met but we can reject + // 35% vote no + let quorum_edgecase = Threshold::ThresholdQuorum { + threshold: Decimal::percent(67), + quorum: Decimal::percent(40), + }; + assert!(check_is_rejected( + quorum_edgecase, + Votes { + yes: 15, + no: 35, + abstain: 0, + veto: 10 + }, + 100, true )); From cd6b88c5e9bf123e6263728012951eba9da54649 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 19:15:32 +0100 Subject: [PATCH 287/631] Cleanup --- contracts/cw20-ics20/src/migrations.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index 536b4da96..8c67b6b49 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -60,16 +60,14 @@ pub mod v2 { Amount::Cw20(coin) => { // FIXME: we should be able to do this with the following line, but QuerierWrapper doesn't play // with the Querier generics - // Cw20Contract(contract.clone()).balance(&deps.querier, contract)? - let msg = Cw20QueryMsg::Balance { - address: contract.into(), - }; + // `Cw20Contract(contract.clone()).balance(&deps.querier, contract)?` let query = WasmQuery::Smart { contract_addr: coin.address, - msg: to_binary(&msg)?, - } - .into(); - let res: BalanceResponse = deps.querier.query(&query)?; + msg: to_binary(&Cw20QueryMsg::Balance { + address: contract.into(), + })?, + }; + let res: BalanceResponse = deps.querier.query(&query.into())?; res.balance } }; From 92e01a4b9cff139bb1733d938a4dde398b18d673 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 24 Mar 2022 18:18:33 +0000 Subject: [PATCH 288/631] Update comment. Circle CI --- contracts/cw3-fixed-multisig/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index eedf1c46e..11d49daf1 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -469,7 +469,7 @@ mod test { 50, false )); - // Can reject when expired + // Can reject when expired. assert!(check_is_rejected( quorum.clone(), rejecting.clone(), From 0899b23b88b1257410c73bbf04f68619b1e842f6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 19:35:39 +0100 Subject: [PATCH 289/631] Add default_gas_limit to InitMsg and Config --- contracts/cw20-ics20/src/contract.rs | 3 +++ contracts/cw20-ics20/src/msg.rs | 4 ++++ contracts/cw20-ics20/src/state.rs | 1 + contracts/cw20-ics20/src/test_helpers.rs | 1 + 4 files changed, 9 insertions(+) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 3c8b25aa9..60b64ff83 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -38,6 +38,7 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { default_timeout: msg.default_timeout, + default_gas_limit: msg.default_gas_limit, }; CONFIG.save(deps.storage, &cfg)?; @@ -233,6 +234,7 @@ pub fn migrate(mut deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result StdResult { let admin = ADMIN.get(deps)?.unwrap_or_else(|| Addr::unchecked("")); let res = ConfigResponse { default_timeout: cfg.default_timeout, + default_gas_limit: cfg.default_gas_limit, gov_contract: admin.into(), }; Ok(res) diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index c5330dd97..778878ada 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -14,6 +14,9 @@ pub struct InitMsg { pub gov_contract: String, /// initial allowlist - all cw20 tokens we will send must be previously allowed by governance pub allowlist: Vec, + /// If set, contracts off the allowlist will run with this gas limit. + /// If unset, will refuse to accept any contract off the allow list. + pub default_gas_limit: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -98,6 +101,7 @@ pub struct PortResponse { #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct ConfigResponse { pub default_timeout: u64, + pub default_gas_limit: Option, pub gov_contract: String, } diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 20277035a..57cbe0a0a 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -32,6 +32,7 @@ pub struct ChannelState { #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { pub default_timeout: u64, + pub default_gas_limit: Option, } #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 27106d66f..6f16a7e1a 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -70,6 +70,7 @@ pub fn setup( // instantiate an empty contract let instantiate_msg = InitMsg { + default_gas_limit: None, default_timeout: DEFAULT_TIMEOUT, gov_contract: "gov".to_string(), allowlist, From 8f82207b845be733963aeffccae17b428a4d9341 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 19:41:10 +0100 Subject: [PATCH 290/631] Add migration entry to set the default_gas_limit --- contracts/cw20-ics20/src/contract.rs | 24 ++++++++++++++++++++++-- contracts/cw20-ics20/src/msg.rs | 4 +++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 60b64ff83..77e0efb8a 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -203,7 +203,7 @@ const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; const MIGRATE_VERSION_3: &str = "0.13.1"; #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(mut deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result { +pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; let stored = get_contract_version(deps.storage)?; let storage_version: Version = stored.version.parse().map_err(from_semver)?; @@ -244,6 +244,15 @@ pub fn migrate(mut deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result StdResult<_> { + old.default_gas_limit = msg.default_gas_limit; + Ok(old) + })?; + } + // we don't need to save anything if migrating from the same version if storage_version < version { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -561,11 +570,22 @@ mod test { .unwrap(); // run migration - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + migrate( + deps.as_mut(), + mock_env(), + MigrateMsg { + default_gas_limit: Some(123456), + }, + ) + .unwrap(); // check new channel state let chan = query_channel(deps.as_ref(), send_channel.into()).unwrap(); assert_eq!(chan.balances, vec![Amount::native(50000, native)]); assert_eq!(chan.total_sent, vec![Amount::native(114000, native)]); + + // check config updates + let config = query_config(deps.as_ref()).unwrap(); + assert_eq!(config.default_gas_limit, Some(123456)); } } diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index 778878ada..6cb68ccbe 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -26,7 +26,9 @@ pub struct AllowMsg { } #[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct MigrateMsg {} +pub struct MigrateMsg { + pub default_gas_limit: Option, +} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] From 41678f490e0d9a9b02c8f6dd5dc0ef2d4bd706df Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 19:47:09 +0100 Subject: [PATCH 291/631] Handle contracts off allow list if default_gas_limit set --- contracts/cw20-ics20/src/contract.rs | 14 +++++++++----- contracts/cw20-ics20/src/ibc.rs | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 77e0efb8a..a9fef4abb 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -108,19 +108,23 @@ pub fn execute_transfer( if !CHANNEL_INFO.has(deps.storage, &msg.channel) { return Err(ContractError::NoSuchChannel { id: msg.channel }); } + let config = CONFIG.load(deps.storage)?; - // if cw20 token, ensure it is whitelisted + // if cw20 token, validate and ensure it is whitelisted, or we set default gas limit if let Amount::Cw20(coin) = &amount { let addr = deps.api.addr_validate(&coin.address)?; - ALLOW_LIST - .may_load(deps.storage, &addr)? - .ok_or(ContractError::NotOnAllowList)?; + // if limit is set, then we always allow cw20 + if config.default_gas_limit.is_none() { + ALLOW_LIST + .may_load(deps.storage, &addr)? + .ok_or(ContractError::NotOnAllowList)?; + } }; // delta from user is in seconds let timeout_delta = match msg.timeout { Some(t) => t, - None => CONFIG.load(deps.storage)?.default_timeout, + None => config.default_timeout, }; // timeout is in nanoseconds let timeout = env.block.time.plus_seconds(timeout_delta); diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index d46121f65..3174584dc 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -12,7 +12,7 @@ use crate::amount::Amount; use crate::error::{ContractError, Never}; use crate::state::{ reduce_channel_balance, undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, - CHANNEL_INFO, REPLY_ARGS, + CHANNEL_INFO, CONFIG, REPLY_ARGS, }; use cw20::Cw20ExecuteMsg; @@ -273,10 +273,14 @@ fn check_gas_limit(deps: Deps, amount: &Amount) -> Result, ContractE Amount::Cw20(coin) => { // if cw20 token, use the registered gas limit, or error if not whitelisted let addr = deps.api.addr_validate(&coin.address)?; - Ok(ALLOW_LIST - .may_load(deps.storage, &addr)? - .ok_or(ContractError::NotOnAllowList)? - .gas_limit) + let allowed = ALLOW_LIST.may_load(deps.storage, &addr)?; + match allowed { + Some(allow) => Ok(allow.gas_limit), + None => match CONFIG.load(deps.storage)?.default_gas_limit { + Some(base) => Ok(Some(base)), + None => Err(ContractError::NotOnAllowList), + }, + } } _ => Ok(None), } From 1ab59a4b0c9bd6b5c7553bd8a771ffddd696094a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 19:57:42 +0100 Subject: [PATCH 292/631] Test the default_gas_limit works properly --- contracts/cw20-ics20/src/contract.rs | 21 ++++++++++++--- contracts/cw20-ics20/src/ibc.rs | 39 ++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index a9fef4abb..894199dea 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -528,9 +528,9 @@ mod test { } #[test] - fn execute_cw20_fails_if_not_whitelisted() { + fn execute_cw20_fails_if_not_whitelisted_unless_default_gas_limit() { let send_channel = "channel-15"; - let mut deps = setup(&["channel-3", send_channel], &[]); + let mut deps = setup(&[send_channel], &[]); let cw20_addr = "my-token"; let transfer = TransferMsg { @@ -544,10 +544,23 @@ mod test { msg: to_binary(&transfer).unwrap(), }); - // works with proper funds + // rejected as not on allow list let info = mock_info(cw20_addr, &[]); - let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); + let err = execute(deps.as_mut(), mock_env(), info.clone(), msg.clone()).unwrap_err(); assert_eq!(err, ContractError::NotOnAllowList); + + // add a default gas limit + migrate( + deps.as_mut(), + mock_env(), + MigrateMsg { + default_gas_limit: Some(123456), + }, + ) + .unwrap(); + + // try again + execute(deps.as_mut(), mock_env(), info, msg).unwrap(); } #[test] diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 3174584dc..80433da32 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -390,8 +390,8 @@ mod test { use super::*; use crate::test_helpers::*; - use crate::contract::{execute, query_channel}; - use crate::msg::{ExecuteMsg, TransferMsg}; + use crate::contract::{execute, migrate, query_channel}; + use crate::msg::{ExecuteMsg, MigrateMsg, TransferMsg}; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::{coins, to_vec, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; use cw20::Cw20ReceiveMsg; @@ -625,4 +625,39 @@ mod test { assert_eq!(state.balances, vec![Amount::native(111111111, denom)]); assert_eq!(state.total_sent, vec![Amount::native(987654321, denom)]); } + + #[test] + fn check_gas_limit_handles_all_cases() { + let send_channel = "channel-9"; + let allowed = "foobar"; + let allowed_gas = 777666; + let mut deps = setup(&[send_channel], &[(allowed, allowed_gas)]); + + // allow list will get proper gas + let limit = check_gas_limit(deps.as_ref(), &Amount::cw20(500, allowed)).unwrap(); + assert_eq!(limit, Some(allowed_gas)); + + // non-allow list will error + let random = "tokenz"; + check_gas_limit(deps.as_ref(), &Amount::cw20(500, random)).unwrap_err(); + + // add default_gas_limit + let def_limit = 54321; + migrate( + deps.as_mut(), + mock_env(), + MigrateMsg { + default_gas_limit: Some(def_limit), + }, + ) + .unwrap(); + + // allow list still gets proper gas + let limit = check_gas_limit(deps.as_ref(), &Amount::cw20(500, allowed)).unwrap(); + assert_eq!(limit, Some(allowed_gas)); + + // non-allow list will now get default + let limit = check_gas_limit(deps.as_ref(), &Amount::cw20(500, random)).unwrap(); + assert_eq!(limit, Some(def_limit)); + } } From bf6be13fbd92bdac62023e4889fa9c357e6be530 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 24 Mar 2022 20:03:58 +0100 Subject: [PATCH 293/631] Set version: 0.13.1 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64a8f025b..ed172e095 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -378,7 +378,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.0" +version = "0.13.1" dependencies = [ "anyhow", "cosmwasm-std", @@ -395,7 +395,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-std", "criterion", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -418,7 +418,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -428,7 +428,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -445,7 +445,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.13.0" +version = "0.13.1" dependencies = [ "anyhow", "assert_matches", @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.13.0" +version = "0.13.1" dependencies = [ "anyhow", "assert_matches", @@ -483,7 +483,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -494,7 +494,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -509,7 +509,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -519,7 +519,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -530,7 +530,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -621,7 +621,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -637,7 +637,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.13.0" +version = "0.13.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 666e7af0a..8913fc731 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw1 = { path = "../../packages/cw1", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw1 = { path = "../../packages/cw1", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.1", features = ["library"] } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index fe81fc847..90445d219 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.13.0" +version = "0.13.1" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw1 = { path = "../../packages/cw1", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw1 = { path = "../../packages/cw1", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 94ee651dc..47da30eb3 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw1 = { path = "../../packages/cw1", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw1 = { path = "../../packages/cw1", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 36650e506..edd5f7399 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.13.0" +version = "0.13.1" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw1155 = { path = "../../packages/cw1155", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index ff894a876..cb05c9620 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw20 = { path = "../../packages/cw20", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 187dbf89d..68c76cb95 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw20 = { path = "../../packages/cw20", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 06b2b40eb..a06f37679 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw3 = { path = "../../packages/cw3", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw3 = { path = "../../packages/cw3", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw20 = { path = "../../packages/cw20", version = "0.13.0" } -cw20-base = { path = "../cw20-base", version = "0.13.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } +cw20 = { path = "../../packages/cw20", version = "0.13.1" } +cw20-base = { path = "../cw20-base", version = "0.13.1", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index ea7d9eb21..673434d5c 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw3 = { path = "../../packages/cw3", version = "0.13.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw3 = { path = "../../packages/cw3", version = "0.13.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.1", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0-beta6" } -cw4-group = { path = "../cw4-group", version = "0.13.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.0" } +cw4-group = { path = "../cw4-group", version = "0.13.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 7e41d420a..610921433 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw4 = { path = "../../packages/cw4", version = "0.13.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw4 = { path = "../../packages/cw4", version = "0.13.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 70c422e85..f5e97cd78 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.0" } -cw4 = { path = "../../packages/cw4", version = "0.13.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw2 = { path = "../../packages/cw2", version = "0.13.1" } +cw4 = { path = "../../packages/cw4", version = "0.13.1" } +cw20 = { path = "../../packages/cw20", version = "0.13.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 28a99ae27..56b12b5f5 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta6" } -cw-utils = { path = "../utils", version = "0.13.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.13.0" } +cw-utils = { path = "../utils", version = "0.13.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index bf0d428d9..ecfe3482d 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 96ab68f95..c5980ff07 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.13.0" +version = "0.13.1" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 501b2eba6..136105e22 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta6", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 383a789cd..d04bd3e6d 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 6720ae812..45c5e4106 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } +cw-utils = { path = "../../packages/utils", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 6ad539d43..e5fe7c8f2 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.1" } cosmwasm-std = { version = "1.0.0-beta6" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index ed91c3c7d..739f233ee 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0"} +cw-utils = { path = "../../packages/utils", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1"} cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta6" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 6032e7384..2b35f106b 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index da0e411f5..8c8a29bac 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.13.0" +version = "0.13.1" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } prost = "0.9" From 0876dcc9ae8453e8fc23fca818c5ce289dcb15e1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 25 Mar 2022 08:32:38 +0100 Subject: [PATCH 294/631] Update CHANGELOG --- CHANGELOG.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff503d3f1..c392dbdb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,29 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.1...HEAD) + +## [v0.13.1](https://github.com/CosmWasm/cw-plus/tree/v0.13.1) (2022-03-25) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.0...v0.13.1) + +**Closed issues:** + +- cw20-base: duplicate accounts get overwritten in Init [\#683](https://github.com/CosmWasm/cw-plus/issues/683) +- Implementation of hooks.rs \(not\) as `HashMap` [\#682](https://github.com/CosmWasm/cw-plus/issues/682) +- Release `cw-plus` v0.13.0 [\#673](https://github.com/CosmWasm/cw-plus/issues/673) +- ICS20, invalid packet data [\#662](https://github.com/CosmWasm/cw-plus/issues/662) +- Duplicate accounts in cw20 initial balances causes unrecoverable inconsistent state [\#626](https://github.com/CosmWasm/cw-plus/issues/626) + +**Merged pull requests:** + +- Add default gas limit to cw20-ics20 [\#685](https://github.com/CosmWasm/cw-plus/pull/685) ([ethanfrey](https://github.com/ethanfrey)) +- Fix cw20 ics20 packets [\#684](https://github.com/CosmWasm/cw-plus/pull/684) ([ethanfrey](https://github.com/ethanfrey)) +- Clarify the stability of cw-storage-plus, no longer Experimental [\#676](https://github.com/CosmWasm/cw-plus/pull/676) ([ethanfrey](https://github.com/ethanfrey)) +- Update changelog add upcoming [\#675](https://github.com/CosmWasm/cw-plus/pull/675) ([maurolacy](https://github.com/maurolacy)) +- Reject proposals early [\#668](https://github.com/CosmWasm/cw-plus/pull/668) ([Callum-A](https://github.com/Callum-A)) +- cw20-base: validate addresses are unique in initial balances [\#659](https://github.com/CosmWasm/cw-plus/pull/659) ([harryscholes](https://github.com/harryscholes)) +- New SECURITY.md refering to wasmd [\#624](https://github.com/CosmWasm/cw-plus/pull/624) ([ethanfrey](https://github.com/ethanfrey)) ## [v0.13.0](https://github.com/CosmWasm/cw-plus/tree/v0.13.0) (2022-03-09) From 34ee531b1646e6f1e525d6b40414893b099e12dd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 25 Mar 2022 08:33:39 +0100 Subject: [PATCH 295/631] Changelog edit for clarity --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c392dbdb5..e2d514dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ - cw20-base: duplicate accounts get overwritten in Init [\#683](https://github.com/CosmWasm/cw-plus/issues/683) - Implementation of hooks.rs \(not\) as `HashMap` [\#682](https://github.com/CosmWasm/cw-plus/issues/682) -- Release `cw-plus` v0.13.0 [\#673](https://github.com/CosmWasm/cw-plus/issues/673) - ICS20, invalid packet data [\#662](https://github.com/CosmWasm/cw-plus/issues/662) - Duplicate accounts in cw20 initial balances causes unrecoverable inconsistent state [\#626](https://github.com/CosmWasm/cw-plus/issues/626) @@ -36,6 +35,7 @@ **Closed issues:** +- Release `cw-plus` v0.13.0 [\#673](https://github.com/CosmWasm/cw-plus/issues/673) - Querying over composite key [\#664](https://github.com/CosmWasm/cw-plus/issues/664) - the method `may_load` exists for struct `cw_storage_plus::Map<'static, (std::string::String, Uint256), Uint256>`, but its trait bounds were not satisfied the following trait bounds were not satisfied: `(std::string::String, Uint256): PrimaryKey` [\#663](https://github.com/CosmWasm/cw-plus/issues/663) - Make `Bound` helpers return `Option` [\#644](https://github.com/CosmWasm/cw-plus/issues/644) From d00b7334a5bfa438bb625f1c052189534c0cc23f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 25 Mar 2022 08:39:14 +0100 Subject: [PATCH 296/631] Update check_contract to latest beta6 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b10f55721..777aff31b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -597,7 +597,7 @@ jobs: - run: name: Install check_contract # Uses --debug for compilation speed - command: cargo install --debug --version 1.0.0-beta4 --features iterator --example check_contract -- cosmwasm-vm + command: cargo install --debug --version 1.0.0-beta6 --features iterator --example check_contract -- cosmwasm-vm - save_cache: paths: - /usr/local/cargo/registry From 51404fe71d63a8738a6b9405fc0d72240f43a838 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 25 Mar 2022 09:16:30 +0100 Subject: [PATCH 297/631] Fix publish.sh help / args --- scripts/publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index afd4c696b..783c3b3b0 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,7 +7,7 @@ function print_usage() { echo "Publishes crates to crates.io." } -if [ "$1" = "-h" ] || [ "$1" = "--help" ] +if [ $# = 1 ] && ( [ "$1" = "-h" ] || [ "$1" = "--help" ] ) then print_usage exit 1 From 7a84bb5326d977345364f76293b47b4ad25a8657 Mon Sep 17 00:00:00 2001 From: MeNoln Date: Sat, 26 Mar 2022 17:24:53 +0300 Subject: [PATCH 298/631] fix type in desc --- contracts/cw20-base/src/msg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index b234ffd1b..8c45fc2fa 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -106,7 +106,7 @@ pub enum QueryMsg { /// Return type: MarketingInfoResponse MarketingInfo {}, /// Only with "marketing" extension - /// Downloads the mbeded logo data (if stored on chain). Errors if no logo data ftored for this + /// Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this /// contract. /// Return type: DownloadLogoResponse. DownloadLogo {}, From 40b5b1587f6952d1320cf3d1c27e2f2b0c287f5a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 27 Mar 2022 08:55:24 +0200 Subject: [PATCH 299/631] Make KeyDeserialize trait public --- packages/storage-plus/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 0d6e464c9..7035d9a25 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -18,6 +18,7 @@ mod snapshot; #[cfg(feature = "iterator")] pub use bound::{Bound, Bounder, PrefixBound, RawBound}; +pub use de::KeyDeserialize; pub use endian::Endian; #[cfg(feature = "iterator")] pub use indexed_map::{IndexList, IndexedMap}; From bffc70fda438ca23371d2a9590f77141d76bd333 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 27 Mar 2022 11:38:20 +0200 Subject: [PATCH 300/631] Fix required trait bounds on raw Map iterators --- packages/storage-plus/src/map.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 398521f3a..82da70a37 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -196,7 +196,7 @@ where impl<'a, K, T> Map<'a, K, T> where T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, + K: PrimaryKey<'a> + Bounder<'a>, { pub fn range_raw<'c>( &self, @@ -223,7 +223,14 @@ where { 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 range<'c>( &self, store: &'c dyn Storage, From b07ce13d394000b79dc4a46a7ae15c16777b2f00 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 27 Mar 2022 11:45:27 +0200 Subject: [PATCH 301/631] Remove optional Bounder trait bound --- packages/storage-plus/src/map.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 82da70a37..eee46f5c1 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -3,7 +3,7 @@ use serde::Serialize; use std::marker::PhantomData; #[cfg(feature = "iterator")] -use crate::bound::{Bound, Bounder, PrefixBound}; +use crate::bound::{Bound, PrefixBound}; #[cfg(feature = "iterator")] use crate::de::KeyDeserialize; use crate::helpers::query_raw; @@ -196,7 +196,7 @@ where impl<'a, K, T> Map<'a, K, T> where T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + Bounder<'a>, + K: PrimaryKey<'a>, { pub fn range_raw<'c>( &self, @@ -229,7 +229,7 @@ where impl<'a, K, T> Map<'a, K, T> where T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize + Bounder<'a>, + K: PrimaryKey<'a> + KeyDeserialize, { pub fn range<'c>( &self, @@ -270,6 +270,9 @@ mod test { #[cfg(feature = "iterator")] use cosmwasm_std::{Order, StdResult}; + #[cfg(feature = "iterator")] + use crate::bound::Bounder; + use crate::int_key::CwIntKey; #[cfg(feature = "iterator")] use crate::IntKeyOld; From c54018fb12d1d64f0e882b5340554b7402fefd12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 29 Mar 2022 16:38:41 +0300 Subject: [PATCH 302/631] storage-plus: Implement u128 key --- packages/storage-plus/src/keys.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index e4240abb1..2af4941ba 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -11,6 +11,7 @@ pub enum Key<'a> { Val16([u8; 2]), Val32([u8; 4]), Val64([u8; 8]), + Val128([u8; 16]), } impl<'a> AsRef<[u8]> for Key<'a> { @@ -21,6 +22,7 @@ impl<'a> AsRef<[u8]> for Key<'a> { Key::Val16(v) => v, Key::Val32(v) => v, Key::Val64(v) => v, + Key::Val128(v) => v } } } @@ -286,7 +288,7 @@ macro_rules! integer_key { } } -integer_key!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); +integer_key!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128); macro_rules! integer_prefix { (for $($t:ty, $v:tt),+) => { @@ -298,7 +300,7 @@ macro_rules! integer_prefix { } } -integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64); +integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128); #[cfg(test)] mod test { @@ -356,6 +358,19 @@ mod test { assert_eq!(4242i64.to_cw_bytes(), path[0].as_ref()); } + #[test] + fn naked_128key_works() { + let k: u128 = 4242u128; + let path = k.key(); + assert_eq!(1, path.len()); + assert_eq!(4242u128.to_cw_bytes(), path[0].as_ref()); + + let k: i128 = 4242i128; + let path = k.key(); + assert_eq!(1, path.len()); + assert_eq!(4242i128.to_cw_bytes(), path[0].as_ref()); + } + #[test] fn str_key_works() { type K<'a> = &'a str; From f0731c060b58bd6437b9870e098c00caa5a49970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 29 Mar 2022 16:58:48 +0300 Subject: [PATCH 303/631] cargo fmt --- packages/storage-plus/src/keys.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 2af4941ba..9e55bfd5b 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -22,7 +22,7 @@ impl<'a> AsRef<[u8]> for Key<'a> { Key::Val16(v) => v, Key::Val32(v) => v, Key::Val64(v) => v, - Key::Val128(v) => v + Key::Val128(v) => v, } } } From 7dc1691633be3f782ff8102f515bc42a44b9bfe2 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Thu, 31 Mar 2022 23:16:03 -0500 Subject: [PATCH 304/631] Fix missing assert --- contracts/cw20-ics20/src/ibc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 80433da32..f5f2dc213 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -557,7 +557,7 @@ mod test { res.messages[0] ); let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); - matches!(ack, Ics20Ack::Result(_)); + assert!(matches!(ack, Ics20Ack::Result(_))); // TODO: we need to call the reply block @@ -616,7 +616,7 @@ mod test { res.messages[0] ); let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); - matches!(ack, Ics20Ack::Result(_)); + assert!(matches!(ack, Ics20Ack::Result(_))); // only need to call reply block on error case From af28db23f092f573eef0f1ee03bba8dfab13f5ad Mon Sep 17 00:00:00 2001 From: Saif Uddin Mahmud Date: Wed, 6 Apr 2022 10:06:24 +0800 Subject: [PATCH 305/631] Remove dead links --- README.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/README.md b/README.md index 062c7fd10..caa5076bf 100644 --- a/README.md +++ b/README.md @@ -127,22 +127,6 @@ CW20 Fungible Tokens: * [`cw20-base`](./contracts/cw20-base) a straightforward, but complete implementation of the cw20 spec along with all extensions. Can be deployed as-is, or imported by other contracts. -* [`cw20-atomic-swap`](./contracts/cw20-atomic-swap) an implementation of atomic swaps for -both native and cw20 tokens. -* [`cw20-bonding`](./contracts/cw20-bonding) a smart contract implementing arbitrary bonding curves, -which can use native and cw20 tokens as reserve tokens. -* [`cw20-staking`](./contracts/cw20-staking) provides staking derivatives, -staking native tokens on your behalf and minting cw20 tokens that can -be used to claim them. It uses `cw20-base` for all the cw20 logic and -only implements the interactions with the staking module and accounting -for prices. -* [`cw20-escrow`](./contracts/cw20-escrow) is a basic escrow contract -(arbiter can release or refund tokens) that is compatible with all native -and cw20 tokens. This is a good example to show how to interact with -cw20 tokens. - -* [`cw20-merkle-airdrop`](./contracts/cw20-merkle-airdrop) is a contract - for efficient cw20 token airdrop distribution. ## Compiling From d5a9937480279c98d44852d85aa9af5c8d7fc50f Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Sat, 9 Apr 2022 12:09:57 +0100 Subject: [PATCH 306/631] multi-test: upgrade to cw-std beta8 and fix next_address --- Cargo.lock | 29 +++++++++++++++-------------- packages/multi-test/Cargo.toml | 4 ++-- packages/multi-test/src/wasm.rs | 3 ++- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed172e095..772b14a40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,22 +155,22 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta6" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dddc1443004c6340e55ca66d98e9d2f1a44aadf4ce2bed2c4f29baa8a15e7b7" +checksum = "37e70111e9701c3ec43bfbff0e523cd4cb115876b4d3433813436dd0934ee962" dependencies = [ "digest", "ed25519-zebra", "k256", - "rand_core 0.5.1", + "rand_core 0.6.3", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta6" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4f0f10f165b8bcc558a13cddb498140960544519aa0581532c766dd80b5598" +checksum = "58bc2ad5d86be5f6068833f63e20786768db6890019c095dd7775232184fb7b3" dependencies = [ "syn", ] @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.0.0-beta6" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0f3145097b692b2d95fa5d2c7c6fdd60f193ccc709857e7e1987a608725300" +checksum = "915ca82bd944f116f3a9717481f3fa657e4a73f28c4887288761ebb24e6fbe10" dependencies = [ "base64", "cosmwasm-crypto", @@ -204,9 +204,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0-beta6" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2945b2c28f64a09e1831f8f830641dc86b39b374c211215e88f2252f474dcb6e" +checksum = "1c4be9fd8c9d3ae7d0c32a925ecbc20707007ce0cba1f7538c0d78b7a2d3729b" dependencies = [ "cosmwasm-std", "serde", @@ -701,16 +701,17 @@ dependencies = [ [[package]] name = "ed25519-zebra" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" dependencies = [ "curve25519-dalek", "hex", - "rand_core 0.5.1", + "rand_core 0.6.3", "serde", "sha2", "thiserror", + "zeroize", ] [[package]] @@ -1358,9 +1359,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uint" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" dependencies = [ "byteorder", "crunchy", diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 739f233ee..ec2664ad2 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,8 +20,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1"} -cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0-beta6" } +cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cosmwasm-storage = { version = "1.0.0-beta8" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 513535230..f8cfacf98 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -779,7 +779,8 @@ where .range_raw(storage, None, None, Order::Ascending) .count(); // we make this longer so it is not rejected by tests - Addr::unchecked(format!("Contract #{}", count)) + // it is lowercase to be compatible with beta8 + Addr::unchecked(format!("contract{}", count)) } fn contract_namespace(&self, contract: &Addr) -> Vec { From 6fe6ca1bd55564c7d21803a00a76b2a6ab89bf28 Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Sat, 9 Apr 2022 13:58:29 +0100 Subject: [PATCH 307/631] Update all cw-std beta6 -> beta8 and all 0.13.1 -> 0.13.2 --- .circleci/config.yml | 2 +- Cargo.lock | 44 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 18 +++++----- contracts/cw1-whitelist-ng/Cargo.toml | 18 +++++----- contracts/cw1-whitelist/Cargo.toml | 16 ++++----- contracts/cw1155-base/Cargo.toml | 14 ++++---- contracts/cw20-base/Cargo.toml | 14 ++++---- contracts/cw20-ics20/Cargo.toml | 16 ++++----- contracts/cw3-fixed-multisig/Cargo.toml | 20 +++++------ contracts/cw3-flex-multisig/Cargo.toml | 22 ++++++------- contracts/cw4-group/Cargo.toml | 16 ++++----- contracts/cw4-stake/Cargo.toml | 18 +++++----- packages/controllers/Cargo.toml | 8 ++--- packages/cw1/Cargo.toml | 6 ++-- packages/cw1155/Cargo.toml | 8 ++--- packages/cw2/Cargo.toml | 6 ++-- packages/cw20/Cargo.toml | 8 ++--- packages/cw3/Cargo.toml | 8 ++--- packages/cw4/Cargo.toml | 8 ++--- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 4 +-- packages/utils/Cargo.toml | 6 ++-- 22 files changed, 143 insertions(+), 143 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 777aff31b..3f195444e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -597,7 +597,7 @@ jobs: - run: name: Install check_contract # Uses --debug for compilation speed - command: cargo install --debug --version 1.0.0-beta6 --features iterator --example check_contract -- cosmwasm-vm + command: cargo install --debug --version 1.0.0-beta8 --features iterator --example check_contract -- cosmwasm-vm - save_cache: paths: - /usr/local/cargo/registry diff --git a/Cargo.lock b/Cargo.lock index 772b14a40..b4efb6445 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,9 +177,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema" -version = "1.0.0-beta6" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497432aa9a8e154e3789845f64049d088eb797ba5a7f78da312153f46c822388" +checksum = "0d75f6a05667d8613b24171ef2c77a8bf6fb9c14f9e3aaa39aa10e0c6416ed67" dependencies = [ "schemars", "serde_json", @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -378,7 +378,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.1" +version = "0.13.2" dependencies = [ "anyhow", "cosmwasm-std", @@ -395,7 +395,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-std", "criterion", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -418,7 +418,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -428,7 +428,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -445,7 +445,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.13.1" +version = "0.13.2" dependencies = [ "anyhow", "assert_matches", @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.13.1" +version = "0.13.2" dependencies = [ "anyhow", "assert_matches", @@ -483,7 +483,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -494,7 +494,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -509,7 +509,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -519,7 +519,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -530,7 +530,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -621,7 +621,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -637,7 +637,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.13.1" +version = "0.13.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 8913fc731..1e10ab7ea 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,17 +19,17 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw1 = { path = "../../packages/cw1", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.1", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw1 = { path = "../../packages/cw1", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library"] } +cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.1", features = ["library", "test-utils"] } +cosmwasm-schema = { version = "1.0.0-beta8" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 90445d219..55eee448a 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.13.1" +version = "0.13.2" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw1 = { path = "../../packages/cw1", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw1 = { path = "../../packages/cw1", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } +cosmwasm-schema = { version = "1.0.0-beta8" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 47da30eb3..f9b549856 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw1 = { path = "../../packages/cw1", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw1 = { path = "../../packages/cw1", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta6" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } +cosmwasm-schema = { version = "1.0.0-beta8" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index edd5f7399..b003fad9c 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.13.1" +version = "0.13.2" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,14 +18,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw1155 = { path = "../../packages/cw1155", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw1155 = { path = "../../packages/cw1155", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index cb05c9620..b82698eb4 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,14 +18,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw20 = { path = "../../packages/cw20", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw20 = { path = "../../packages/cw20", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 68c76cb95..74c101605 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,16 +18,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw20 = { path = "../../packages/cw20", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw20 = { path = "../../packages/cw20", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8", features = ["stargate"] } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index a06f37679..fab4ea012 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,17 +18,17 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw3 = { path = "../../packages/cw3", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw3 = { path = "../../packages/cw3", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } -cw20 = { path = "../../packages/cw20", version = "0.13.1" } -cw20-base = { path = "../cw20-base", version = "0.13.1", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } +cosmwasm-schema = { version = "1.0.0-beta8" } +cw20 = { path = "../../packages/cw20", version = "0.13.2" } +cw20-base = { path = "../cw20-base", version = "0.13.2", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 673434d5c..16039cb72 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,18 +18,18 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw3 = { path = "../../packages/cw3", version = "0.13.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.1", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw3 = { path = "../../packages/cw3", version = "0.13.2" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.2", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } -cw4-group = { path = "../cw4-group", version = "0.13.1" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.1" } +cosmwasm-schema = { version = "1.0.0-beta8" } +cw4-group = { path = "../cw4-group", version = "0.13.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 610921433..a1b7e07ef 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,15 +26,15 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw4 = { path = "../../packages/cw4", version = "0.13.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw4 = { path = "../../packages/cw4", version = "0.13.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index f5e97cd78..c0dfb9286 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,16 +26,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw2 = { path = "../../packages/cw2", version = "0.13.1" } -cw4 = { path = "../../packages/cw4", version = "0.13.1" } -cw20 = { path = "../../packages/cw20", version = "0.13.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw4 = { path = "../../packages/cw4", version = "0.13.2" } +cw20 = { path = "../../packages/cw20", version = "0.13.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 56b12b5f5..ed8607745 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -12,9 +12,9 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta6" } -cw-utils = { path = "../utils", version = "0.13.1" } -cw-storage-plus = { path = "../storage-plus", version = "0.13.1" } +cosmwasm-std = { version = "1.0.0-beta8" } +cw-utils = { path = "../utils", version = "0.13.2" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index ecfe3482d..f3584ce5b 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta6" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index c5980ff07..2ce6796aa 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.13.1" +version = "0.13.2" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,10 +10,10 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 136105e22..5b0ea1997 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta6", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cosmwasm-std = { version = "1.0.0-beta8", default-features = false } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index d04bd3e6d..353ab8d9b 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,10 +10,10 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 45c5e4106..6a9d45b41 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,10 +10,10 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index e5fe7c8f2..9d9c972bb 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,10 +10,10 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.13.1" } -cosmwasm-std = { version = "1.0.0-beta6" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta6" } +cosmwasm-schema = { version = "1.0.0-beta8" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index ec2664ad2..82505a7ba 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1"} +cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2"} cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } cosmwasm-storage = { version = "1.0.0-beta8" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 2b35f106b..6656060d1 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -18,7 +18,7 @@ iterator = ["cosmwasm-std/iterator"] bench = false [dependencies] -cosmwasm-std = { version = "1.0.0-beta6", default-features = false } +cosmwasm-std = { version = "1.0.0-beta8", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 8c8a29bac..26e25d475 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.13.1" +version = "0.13.2" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -12,11 +12,11 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta6" } +cosmwasm-std = { version = "1.0.0-beta8" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } prost = "0.9" From bc2aa29f3e7c55d2086cbec53ff4fd40e7197e7e Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Sat, 9 Apr 2022 14:03:56 +0100 Subject: [PATCH 308/631] Update code comment as suggested by @webmaster128 --- packages/multi-test/src/wasm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index f8cfacf98..8182bc3c4 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -779,7 +779,7 @@ where .range_raw(storage, None, None, Order::Ascending) .count(); // we make this longer so it is not rejected by tests - // it is lowercase to be compatible with beta8 + // it is lowercase to be compatible with the MockApi implementation of cosmwasm-std >= 1.0.0-beta8 Addr::unchecked(format!("contract{}", count)) } From 37c0a5acd5b10c6e44d191a33edbaed6e5083f0c Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Sat, 9 Apr 2022 14:05:42 +0100 Subject: [PATCH 309/631] Update current version for v3 in ics20 --- contracts/cw20-ics20/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 894199dea..bcb71733c 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -204,7 +204,7 @@ pub fn execute_allow( const MIGRATE_MIN_VERSION: &str = "0.11.1"; const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; -const MIGRATE_VERSION_3: &str = "0.13.1"; +const MIGRATE_VERSION_3: &str = "0.13.2"; #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { From f36ed40df1d21e3e0a914efdd6535cbeab78981c Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Mon, 11 Apr 2022 21:27:51 -0400 Subject: [PATCH 310/631] Add has to indexed map --- packages/storage-plus/src/indexed_map.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 1771b0df2..062d7ce96 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -130,6 +130,12 @@ where self.primary.may_load(store, key) } + /// has returns true or false if any data is at this key, without parsing or interpreting the + /// contents. + pub fn has(&self, store: &dyn Storage, k: K) -> bool { + self.primary.key(k).has(store) + } + // use no_prefix to scan -> range fn no_prefix_raw(&self) -> Prefix, T, K> { Prefix::new(self.pk_namespace, &[]) @@ -519,6 +525,24 @@ mod test { assert_eq!(None, aged); } + #[test] + fn existence() { + let mut store = MockStorage::new(); + let map = build_map(); + + // save data + let (pks, datas) = save_data(&mut store, &map); + let pk = pks[0]; + let data = &datas[0]; + + // load it properly + let loaded = map.load(&store, pk).unwrap(); + assert_eq!(*data, loaded); + + assert!(map.has(&store, pks[1])); + assert!(!map.has(&store, "6")); + } + #[test] fn range_raw_simple_key_by_multi_index() { let mut store = MockStorage::new(); From ddd2351b1cae086d4f9cc4d43e85260c4e44dc1f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 13 Apr 2022 08:30:19 +0200 Subject: [PATCH 311/631] Update link to new shared CosmWasm SECURITY.md --- SECURITY.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 1b10ff8e5..830ec1711 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,9 @@ # Security Policy +This repository is maintained by Confio as part of the CosmWasm stack. +Please see https://github.com/CosmWasm/advisories/blob/main/SECURITY.md +for our security policy. + ## Supported Versions cw-plus is still pre v1.0. A best effort has been made that the contracts here are secure, and we have moved the more @@ -10,9 +14,3 @@ with significant token value, and please inform us if it detects any issues so w Until v1.0 APIs are subject to change. The contracts APIs are pretty much stable, most work is currently in `storage-plus` and `multi-test`. - -## Reporting a Vulnerability - -We have a [unified security policy](https://github.com/CosmWasm/wasmd/blob/master/SECURITY.md) -for all CosmWasm-related repositories maintained by Confio. -You can [read it here](https://github.com/CosmWasm/wasmd/blob/master/SECURITY.md) From 9b8102ab490d63205b4856b2e38e16a3d8123b0c Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Wed, 13 Apr 2022 15:34:57 +0100 Subject: [PATCH 312/631] Handle duplicate members in cw4-group create --- contracts/cw4-group/src/contract.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 913d427f6..d7952d9c3 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -51,7 +51,12 @@ pub fn create( for member in members.into_iter() { total += member.weight; let member_addr = deps.api.addr_validate(&member.addr)?; - MEMBERS.save(deps.storage, &member_addr, &member.weight, height)?; + MEMBERS.update(deps.storage, &member_addr, height, |v| -> StdResult { + match v { + Some(weight) => Ok(weight + member.weight), + None => Ok(member.weight), + } + })?; } TOTAL.save(deps.storage, &total)?; @@ -229,7 +234,11 @@ mod tests { }, Member { addr: USER2.into(), - weight: 6, + weight: 2, + }, + Member { + addr: USER2.into(), + weight: 4, }, ], }; From 1b09774fdc6436d6766d2350bdb4fd0617e52d07 Mon Sep 17 00:00:00 2001 From: "shane.stars" Date: Thu, 14 Apr 2022 09:26:32 -0400 Subject: [PATCH 313/631] Update packages/storage-plus/src/indexed_map.rs Co-authored-by: Jakub Bogucki --- packages/storage-plus/src/indexed_map.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 062d7ce96..a70bb412b 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -130,8 +130,7 @@ where self.primary.may_load(store, key) } - /// has returns true or false if any data is at this key, without parsing or interpreting the - /// contents. + /// Returns true if storage contains this key, without parsing or interpreting the contents. pub fn has(&self, store: &dyn Storage, k: K) -> bool { self.primary.key(k).has(store) } From b40bdcaa8138e7063dd2773c94db6c7422d60e82 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Thu, 14 Apr 2022 09:31:48 -0400 Subject: [PATCH 314/631] Simplified test --- packages/storage-plus/src/indexed_map.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index a70bb412b..55d572958 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -528,17 +528,9 @@ mod test { fn existence() { let mut store = MockStorage::new(); let map = build_map(); + let (pks, _) = save_data(&mut store, &map); - // save data - let (pks, datas) = save_data(&mut store, &map); - let pk = pks[0]; - let data = &datas[0]; - - // load it properly - let loaded = map.load(&store, pk).unwrap(); - assert_eq!(*data, loaded); - - assert!(map.has(&store, pks[1])); + assert!(map.has(&store, pks[0])); assert!(!map.has(&store, "6")); } From 57df1d9e23f23ef47f50beca4614cb52a896698f Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 20 Apr 2022 13:34:46 -0400 Subject: [PATCH 315/631] Move test helpers into a test section --- packages/storage-plus/src/indexed_map.rs | 4 +-- packages/storage-plus/src/indexed_snapshot.rs | 4 +-- packages/storage-plus/src/indexes/mod.rs | 36 ++++++++++--------- packages/storage-plus/src/lib.rs | 4 +-- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 55d572958..ca2ba8b78 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -277,8 +277,8 @@ where mod test { use super::*; - use crate::indexes::index_string_tuple; - use crate::{index_tuple, MultiIndex, UniqueIndex}; + use crate::indexes::test::{index_string_tuple, index_tuple}; + use crate::{MultiIndex, UniqueIndex}; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{MemoryStorage, Order}; use serde::{Deserialize, Serialize}; diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 2b152abb3..89987551e 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -302,8 +302,8 @@ where mod test { use super::*; - use crate::indexes::index_string_tuple; - use crate::{index_tuple, Index, MultiIndex, UniqueIndex}; + use crate::indexes::test::{index_string_tuple, index_tuple}; + use crate::{Index, MultiIndex, UniqueIndex}; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{MemoryStorage, Order}; use serde::{Deserialize, Serialize}; diff --git a/packages/storage-plus/src/indexes/mod.rs b/packages/storage-plus/src/indexes/mod.rs index ad7e8b46a..7c6bed1d6 100644 --- a/packages/storage-plus/src/indexes/mod.rs +++ b/packages/storage-plus/src/indexes/mod.rs @@ -11,22 +11,6 @@ use serde::Serialize; use cosmwasm_std::{StdResult, Storage}; -pub fn index_string(data: &str) -> Vec { - data.as_bytes().to_vec() -} - -pub fn index_tuple(name: &str, age: u32) -> (Vec, u32) { - (index_string(name), age) -} - -pub fn index_triple(name: &str, age: u32, pk: Vec) -> (Vec, u32, Vec) { - (index_string(name), age, pk) -} - -pub fn index_string_tuple(data1: &str, data2: &str) -> (Vec, Vec) { - (index_string(data1), index_string(data2)) -} - // Note: we cannot store traits with generic functions inside `Box`, // so I pull S: Storage to a top-level pub trait Index @@ -36,3 +20,23 @@ where fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()>; fn remove(&self, store: &mut dyn Storage, pk: &[u8], old_data: &T) -> StdResult<()>; } + +#[cfg(test)] +pub mod test { + + pub fn index_string(data: &str) -> Vec { + data.as_bytes().to_vec() + } + + pub fn index_tuple(name: &str, age: u32) -> (Vec, u32) { + (index_string(name), age) + } + + pub fn index_triple(name: &str, age: u32, pk: Vec) -> (Vec, u32, Vec) { + (index_string(name), age, pk) + } + + pub fn index_string_tuple(data1: &str, data2: &str) -> (Vec, Vec) { + (index_string(data1), index_string(data2)) + } +} diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 7035d9a25..5562073c0 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -25,11 +25,11 @@ pub use indexed_map::{IndexList, IndexedMap}; #[cfg(feature = "iterator")] pub use indexed_snapshot::IndexedSnapshotMap; #[cfg(feature = "iterator")] +pub use indexes::Index; +#[cfg(feature = "iterator")] pub use indexes::MultiIndex; #[cfg(feature = "iterator")] pub use indexes::UniqueIndex; -#[cfg(feature = "iterator")] -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}; From bdef5d6a2391db54fca3d6d8e226abdf8c1c1be2 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 20 Apr 2022 13:41:03 -0400 Subject: [PATCH 316/631] Removed dead code --- packages/storage-plus/src/indexes/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/storage-plus/src/indexes/mod.rs b/packages/storage-plus/src/indexes/mod.rs index 7c6bed1d6..e2639ac83 100644 --- a/packages/storage-plus/src/indexes/mod.rs +++ b/packages/storage-plus/src/indexes/mod.rs @@ -32,10 +32,6 @@ pub mod test { (index_string(name), age) } - pub fn index_triple(name: &str, age: u32, pk: Vec) -> (Vec, u32, Vec) { - (index_string(name), age, pk) - } - pub fn index_string_tuple(data1: &str, data2: &str) -> (Vec, Vec) { (index_string(data1), index_string(data2)) } From d4ec5c7e039908cb722f4b9785b58c309e7fc4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Fri, 22 Apr 2022 14:58:56 +0200 Subject: [PATCH 317/631] Removed documentation from Cargo.toml --- packages/controllers/Cargo.toml | 1 - packages/cw1/Cargo.toml | 1 - packages/cw1155/Cargo.toml | 1 - packages/cw2/Cargo.toml | 1 - packages/cw20/Cargo.toml | 1 - packages/cw3/Cargo.toml | 1 - packages/cw4/Cargo.toml | 1 - packages/multi-test/Cargo.toml | 1 - packages/storage-plus/Cargo.toml | 1 - packages/utils/Cargo.toml | 1 - 10 files changed, 10 deletions(-) diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index ed8607745..5dc42a747 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -7,7 +7,6 @@ description = "Common controllers we can reuse in many contracts" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index f3584ce5b..a4ff1b55d 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -7,7 +7,6 @@ description = "Definition and types for the CosmWasm-1 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta8" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 2ce6796aa..140166170 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -7,7 +7,6 @@ description = "Definition and types for the CosmWasm-1155 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 5b0ea1997..10974798a 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -7,7 +7,6 @@ description = "Definition and types for the CosmWasm-2 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0-beta8", default-features = false } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 353ab8d9b..88738a164 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -7,7 +7,6 @@ description = "Definition and types for the CosmWasm-20 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 6a9d45b41..97bf2144f 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -7,7 +7,6 @@ description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 9d9c972bb..bed66b033 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -7,7 +7,6 @@ description = "CosmWasm-4 Interface: Groups Members" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 82505a7ba..96d0e09b1 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -7,7 +7,6 @@ description = "Test helpers for multi-contract interactions" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 6656060d1..e51ab096c 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -7,7 +7,6 @@ description = "Enhanced storage engines" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" [features] default = ["iterator"] diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 26e25d475..965d63024 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -7,7 +7,6 @@ description = "Common helpers for other cw specs" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 3f5a3cd9475d45d11a424e5593b32195bb6825b3 Mon Sep 17 00:00:00 2001 From: Artie Kushner <34076599+rtviii@users.noreply.github.com> Date: Wed, 27 Apr 2022 18:31:21 -0700 Subject: [PATCH 318/631] Update item.rs --- packages/storage-plus/src/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/item.rs b/packages/storage-plus/src/item.rs index 312a87fef..78ec3b73e 100644 --- a/packages/storage-plus/src/item.rs +++ b/packages/storage-plus/src/item.rs @@ -10,7 +10,7 @@ use crate::helpers::{may_deserialize, must_deserialize}; /// Item stores one typed item at the given key. /// This is an analog of Singleton. -/// It functions just as Path but doesn't ue a Vec and thus has a const fn constructor. +/// It functions the same way Path does but doesn't use a Vec and thus has a const fn constructor. pub struct Item<'a, T> { // this is full key - no need to length-prefix it, we only store one item storage_key: &'a [u8], From 057786e329a033df1ac0e3e38acd24d51ce48d28 Mon Sep 17 00:00:00 2001 From: Artie Kushner <34076599+rtviii@users.noreply.github.com> Date: Thu, 28 Apr 2022 10:48:22 -0700 Subject: [PATCH 319/631] Update packages/storage-plus/src/item.rs Co-authored-by: Jakub Bogucki --- packages/storage-plus/src/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/item.rs b/packages/storage-plus/src/item.rs index 78ec3b73e..865fd534e 100644 --- a/packages/storage-plus/src/item.rs +++ b/packages/storage-plus/src/item.rs @@ -10,7 +10,7 @@ use crate::helpers::{may_deserialize, must_deserialize}; /// Item stores one typed item at the given key. /// This is an analog of Singleton. -/// It functions the same way Path does but doesn't use a Vec and thus has a const fn constructor. +/// It functions the same way as Path does but doesn't use a Vec and thus has a const fn constructor. pub struct Item<'a, T> { // this is full key - no need to length-prefix it, we only store one item storage_key: &'a [u8], From 1729df0f3ac7078a823b8e35e92863abe1495055 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 13:03:59 +0200 Subject: [PATCH 320/631] Add tarpaulin code coverage to CI --- .circleci/config.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f195444e..87179718b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,6 +34,15 @@ workflows: # Long living branches - main # 👇Add your branch here if benchmarking matters to your work + coverage: + jobs: + - coverage: + filters: + branches: + only: + # Long living branches + - main + # 👇Add your branch here if code coverage matters to your work deploy: jobs: - build_and_upload_contracts: @@ -695,6 +704,15 @@ jobs: - target key: cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + # This job follows the instructions from https://github.com/xd009642/tarpaulin#circleci + coverage: + machine: true + steps: + - checkout + - run: + name: Coverage with tarpaulin docker image + command: docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin + # This job roughly follows the instructions from https://circleci.com/blog/publishing-to-github-releases-via-circleci/ build_and_upload_contracts: docker: From ed1803c5126dc592307fc1be5dabea5fabd2cd87 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 13:10:12 +0200 Subject: [PATCH 321/631] Add dev branch to code coverage --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87179718b..fc78e0fd1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,6 +43,7 @@ workflows: # Long living branches - main # 👇Add your branch here if code coverage matters to your work + - 172-code-coverage deploy: jobs: - build_and_upload_contracts: From 764faa5a0fa4c1c5200d5258ac1fa4ecc2c97d28 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 13:27:18 +0200 Subject: [PATCH 322/631] Switch to a supported image in machine job --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fc78e0fd1..0772c066a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -707,7 +707,8 @@ jobs: # This job follows the instructions from https://github.com/xd009642/tarpaulin#circleci coverage: - machine: true + machine: + image: ubuntu-2004:202201-02 steps: - checkout - run: From 459afb62b316bdea450061d1c23952f9ec54f799 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 16:03:37 +0200 Subject: [PATCH 323/631] Add codecov orb for coverage results --- .circleci/config.yml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0772c066a..53e9b69ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,8 @@ -version: 2 +version: 2.1 + +orbs: + codecov: codecov/codecov@3.2.2 + workflows: version: 2 test: @@ -34,6 +38,7 @@ workflows: # Long living branches - main # 👇Add your branch here if benchmarking matters to your work + coverage: jobs: - coverage: @@ -705,15 +710,20 @@ jobs: - target key: cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - # This job follows the instructions from https://github.com/xd009642/tarpaulin#circleci coverage: + # https://circleci.com/developer/images?imageType=machine machine: image: ubuntu-2004:202201-02 steps: - checkout - run: - name: Coverage with tarpaulin docker image - command: docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin + name: Run tests with coverage + command: | + mkdir -p cov + docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin \ + sh -c "cargo tarpaulin --skip-clean --frozen --out Xml --output-dir cov" + - codecov/upload: + file: cov/cobertura.html # This job roughly follows the instructions from https://circleci.com/blog/publishing-to-github-releases-via-circleci/ build_and_upload_contracts: From 306a683e5550b968371ccae0f58ff10c23e7d69f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 17:57:37 +0200 Subject: [PATCH 324/631] Add codecov setup file --- codecov.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..acfcbf4ca --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +comment: false + +coverage: + status: + project: + default: + threshold: 0.05% + patch: + default: + threshold: 0.05% + +ignore: + +flags: From 966eab9526f1195a3edcfeb218772df2d375dc47 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 18:07:43 +0200 Subject: [PATCH 325/631] Fix cobertura file extension --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 53e9b69ed..69d611fce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -723,7 +723,7 @@ jobs: docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin \ sh -c "cargo tarpaulin --skip-clean --frozen --out Xml --output-dir cov" - codecov/upload: - file: cov/cobertura.html + file: cov/cobertura.xml # This job roughly follows the instructions from https://circleci.com/blog/publishing-to-github-releases-via-circleci/ build_and_upload_contracts: From ef69301e30cfff941e01f3ebe5ee162a8dbbc87b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 21:20:28 +0200 Subject: [PATCH 326/631] Fix: validated codecov.yml --- codecov.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index acfcbf4ca..a33250820 100644 --- a/codecov.yml +++ b/codecov.yml @@ -10,5 +10,3 @@ coverage: threshold: 0.05% ignore: - -flags: From d740cb1e5a33cc8fa40d7363a27527db21a1dec2 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 3 May 2022 21:45:06 +0200 Subject: [PATCH 327/631] Add cove coverage badge to README --- README.md | 59 +++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index caa5076bf..cd56c7cae 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,34 @@ # CosmWasm Plus -[![CircleCI](https://circleci.com/gh/CosmWasm/cw-plus/tree/master.svg?style=shield)](https://circleci.com/gh/CosmWasm/cw-plus/tree/master) - -| Specification | Crates.io | Docs | -| ---------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------| -| cw1 | [![cw1 on crates.io](https://img.shields.io/crates/v/cw1.svg)](https://crates.io/crates/cw1) | [![Docs](https://docs.rs/cw1/badge.svg)](https://docs.rs/cw1) | -| cw2 | [![cw2 on crates.io](https://img.shields.io/crates/v/cw2.svg)](https://crates.io/crates/cw2) | [![Docs](https://docs.rs/cw2/badge.svg)](https://docs.rs/cw2) | -| cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | -| cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | -| cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | -| cw1155 | [![cw1155 on crates.io](https://img.shields.io/crates/v/cw1155.svg)](https://crates.io/crates/cw1155) | [![Docs](https://docs.rs/cw1155/badge.svg)](https://docs.rs/cw1155) | - -| Utilities | Crates.io | Docs | -| ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------| -| cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | -| cw-multi-test | [![cw-multi-test on crates.io](https://img.shields.io/crates/v/cw-multi-test.svg)](https://crates.io/crates/cw-multi-test) | [![Docs](https://docs.rs/cw-multi-test/badge.svg)](https://docs.rs/cw-multi-test) | -| cw-storage-plus | [![cw-storage-plus on crates.io](https://img.shields.io/crates/v/cw-storage-plus.svg)](https://crates.io/crates/cw-storage-plus) | [![Docs](https://docs.rs/cw-storage-plus/badge.svg)](https://docs.rs/cw-storage-plus) | -| cw-utils | [![cw-utils on crates.io](https://img.shields.io/crates/v/cw-utils.svg)](https://crates.io/crates/cw-utils) | [![Docs](https://docs.rs/cw-utils/badge.svg)](https://docs.rs/cw-utils) | - -| Contracts | Download | Docs | -| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------| -| cw1-subkeys | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | -| cw1-whitelist | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_whitelist.wasm) | [![Docs](https://docs.rs/cw1-whitelist/badge.svg)](https://docs.rs/cw1-whitelist) | -| cw3-fixed-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_fixed_multisig.wasm) | [![Docs](https://docs.rs/cw3-fixed-multisig/badge.svg)](https://docs.rs/cw3-fixed-multisig) | -| cw3-flex-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_flex_multisig.wasm) | [![Docs](https://docs.rs/cw3-flex-multisig/badge.svg)](https://docs.rs/cw3-flex-multisig) | -| cw4-group | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_group.wasm) | [![Docs](https://docs.rs/cw4-group/badge.svg)](https://docs.rs/cw4-group) | -| cw4-stake | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | -| cw20-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | -| cw20-ics20 | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | -| cw1155-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | - +[![CircleCI](https://circleci.com/gh/CosmWasm/cw-plus/tree/main.svg?style=shield)](https://circleci.com/gh/CosmWasm/cw-plus/tree/main) + +| Specification | Crates.io | Docs | Coverage | +|---------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| +| cw1 | [![cw1 on crates.io](https://img.shields.io/crates/v/cw1.svg)](https://crates.io/crates/cw1) | [![Docs](https://docs.rs/cw1/badge.svg)](https://docs.rs/cw1) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw2 | [![cw2 on crates.io](https://img.shields.io/crates/v/cw2.svg)](https://crates.io/crates/cw2) | [![Docs](https://docs.rs/cw2/badge.svg)](https://docs.rs/cw2) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1155 | [![cw1155 on crates.io](https://img.shields.io/crates/v/cw1155.svg)](https://crates.io/crates/cw1155) | [![Docs](https://docs.rs/cw1155/badge.svg)](https://docs.rs/cw1155) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | + +| Utilities | Crates.io | Docs | Coverage | +|-----------------|----------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| +| cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw-multi-test | [![cw-multi-test on crates.io](https://img.shields.io/crates/v/cw-multi-test.svg)](https://crates.io/crates/cw-multi-test) | [![Docs](https://docs.rs/cw-multi-test/badge.svg)](https://docs.rs/cw-multi-test) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | +| cw-storage-plus | [![cw-storage-plus on crates.io](https://img.shields.io/crates/v/cw-storage-plus.svg)](https://crates.io/crates/cw-storage-plus) | [![Docs](https://docs.rs/cw-storage-plus/badge.svg)](https://docs.rs/cw-storage-plus) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw-utils | [![cw-utils on crates.io](https://img.shields.io/crates/v/cw-utils.svg)](https://crates.io/crates/cw-utils) | [![Docs](https://docs.rs/cw-utils/badge.svg)](https://docs.rs/cw-utils) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | + +| Contracts | Download | Docs | Coverage | +|--------------------|----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| +| cw1-subkeys | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1-whitelist | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_whitelist.wasm) | [![Docs](https://docs.rs/cw1-whitelist/badge.svg)](https://docs.rs/cw1-whitelist) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3-fixed-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_fixed_multisig.wasm) | [![Docs](https://docs.rs/cw3-fixed-multisig/badge.svg)](https://docs.rs/cw3-fixed-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3-flex-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_flex_multisig.wasm) | [![Docs](https://docs.rs/cw3-flex-multisig/badge.svg)](https://docs.rs/cw3-flex-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4-group | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_group.wasm) | [![Docs](https://docs.rs/cw4-group/badge.svg)](https://docs.rs/cw4-group) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4-stake | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20-ics20 | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1155-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be followed there. From 58348b80553d8af7a68cce5b9dc15176833373ba Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 5 May 2022 08:26:09 +0200 Subject: [PATCH 328/631] Run coverage on all branches Run coverage as part of tests --- .circleci/config.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 69d611fce..f62325e34 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,17 +38,7 @@ workflows: # Long living branches - main # 👇Add your branch here if benchmarking matters to your work - - coverage: - jobs: - - coverage: - filters: - branches: - only: - # Long living branches - - main - # 👇Add your branch here if code coverage matters to your work - - 172-code-coverage + - coverage deploy: jobs: - build_and_upload_contracts: From b923f8ada766187956081af2de6dd2f6403d3853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Mon, 16 May 2022 13:58:56 +0200 Subject: [PATCH 329/631] Repo reclippization --- Cargo.lock | 264 ++++++++++-------- packages/multi-test/src/executor.rs | 7 +- .../src/test_helpers/contracts/echo.rs | 22 +- packages/multi-test/src/wasm.rs | 4 +- packages/storage-plus/src/prefix.rs | 3 +- packages/utils/src/parse_reply.rs | 6 +- 6 files changed, 171 insertions(+), 135 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4efb6445..df3eb49ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" dependencies = [ "backtrace", ] @@ -51,9 +51,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" dependencies = [ "addr2line", "cc", @@ -64,12 +64,24 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" + [[package]] name = "bitflags" version = "1.3.2" @@ -149,15 +161,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e70111e9701c3ec43bfbff0e523cd4cb115876b4d3433813436dd0934ee962" +checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" dependencies = [ "digest", "ed25519-zebra", @@ -168,18 +180,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc2ad5d86be5f6068833f63e20786768db6890019c095dd7775232184fb7b3" +checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0-beta8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d75f6a05667d8613b24171ef2c77a8bf6fb9c14f9e3aaa39aa10e0c6416ed67" +checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" dependencies = [ "schemars", "serde_json", @@ -187,9 +199,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.0.0-beta8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915ca82bd944f116f3a9717481f3fa657e4a73f28c4887288761ebb24e6fbe10" +checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" dependencies = [ "base64", "cosmwasm-crypto", @@ -204,9 +216,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0-beta8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4be9fd8c9d3ae7d0c32a925ecbc20707007ce0cba1f7538c0d78b7a2d3729b" +checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" dependencies = [ "cosmwasm-std", "serde", @@ -214,9 +226,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -259,9 +271,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if", "crossbeam-utils", @@ -280,10 +292,11 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ + "autocfg", "cfg-if", "crossbeam-utils", "lazy_static", @@ -293,9 +306,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if", "lazy_static", @@ -309,9 +322,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.2.11" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -654,9 +667,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ "const-oid", ] @@ -683,19 +696,19 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" +checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" [[package]] name = "ecdsa" -version = "0.12.4" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" dependencies = [ "der", "elliptic-curve", - "hmac", + "rfc6979", "signature", ] @@ -722,25 +735,27 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.10.6" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" dependencies = [ + "base16ct", "crypto-bigint", + "der", "ff", "generic-array", "group", - "pkcs8", "rand_core 0.6.3", + "sec1", "subtle", "zeroize", ] [[package]] name = "ff" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" dependencies = [ "rand_core 0.6.3", "subtle", @@ -775,9 +790,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -792,9 +807,9 @@ checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] name = "group" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ "ff", "rand_core 0.6.3", @@ -849,28 +864,29 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.9.6" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", + "sec1", "sha2", ] @@ -882,24 +898,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -912,19 +928,18 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -941,9 +956,9 @@ dependencies = [ [[package]] name = "object" -version = "0.27.1" +version = "0.28.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ "memchr", ] @@ -962,12 +977,13 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.7.6" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ "der", "spki", + "zeroize", ] [[package]] @@ -1006,9 +1022,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" dependencies = [ "unicode-xid", ] @@ -1038,9 +1054,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -1081,14 +1097,14 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", ] [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -1098,14 +1114,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] @@ -1130,6 +1145,17 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "rfc6979" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -1147,9 +1173,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "same-file" @@ -1190,26 +1216,39 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sec1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +dependencies = [ + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "semver" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" dependencies = [ "serde", ] @@ -1226,9 +1265,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -1248,11 +1287,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "itoa 1.0.1", + "itoa 1.0.2", "ryu", "serde", ] @@ -1272,9 +1311,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" +checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" dependencies = [ "digest", "rand_core 0.6.3", @@ -1282,10 +1321,11 @@ dependencies = [ [[package]] name = "spki" -version = "0.4.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ + "base64ct", "der", ] @@ -1303,9 +1343,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" dependencies = [ "proc-macro2", "quote", @@ -1323,18 +1363,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -1377,9 +1417,9 @@ checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "version_check" @@ -1412,9 +1452,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1422,9 +1462,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", @@ -1437,9 +1477,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1447,9 +1487,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -1460,15 +1500,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -1507,6 +1547,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zeroize" -version = "1.4.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs index b6eb341e1..75be02d60 100644 --- a/packages/multi-test/src/executor.rs +++ b/packages/multi-test/src/executor.rs @@ -1,8 +1,7 @@ use std::fmt; use cosmwasm_std::{ - to_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, Event, SubMsgExecutionResponse, - WasmMsg, + to_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, Event, SubMsgResponse, WasmMsg, }; use cw_utils::{parse_execute_response_data, parse_instantiate_response_data}; use schemars::JsonSchema; @@ -52,8 +51,8 @@ impl AppResponse { /// They have the same shape, SubMsgExecutionResponse is what is returned in reply. /// This is just to make some test cases easier. -impl From for AppResponse { - fn from(reply: SubMsgExecutionResponse) -> Self { +impl From for AppResponse { + fn from(reply: SubMsgResponse) -> Self { AppResponse { data: reply.data, events: reply.events, diff --git a/packages/multi-test/src/test_helpers/contracts/echo.rs b/packages/multi-test/src/test_helpers/contracts/echo.rs index c1d51b3a5..fb87602a6 100644 --- a/packages/multi-test/src/test_helpers/contracts/echo.rs +++ b/packages/multi-test/src/test_helpers/contracts/echo.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ to_binary, Attribute, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Reply, Response, - StdError, SubMsg, SubMsgExecutionResponse, SubMsgResult, + StdError, SubMsg, SubMsgResponse, SubMsgResult, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -97,24 +97,22 @@ where let res = Response::new(); if let Reply { id, - result: - SubMsgResult::Ok(SubMsgExecutionResponse { - data: Some(data), .. - }), + result: SubMsgResult::Ok(SubMsgResponse { + data: Some(data), .. + }), } = msg { // We parse out the WasmMsg::Execute wrapper... // TODO: Handle all of Execute, Instantiate, and BankMsg replies differently. - let parsed_data; - if id < EXECUTE_REPLY_BASE_ID { - parsed_data = parse_instantiate_response_data(data.as_slice()) + let parsed_data = if id < EXECUTE_REPLY_BASE_ID { + parse_instantiate_response_data(data.as_slice()) .map_err(|e| StdError::generic_err(e.to_string()))? - .data; + .data } else { - parsed_data = parse_execute_response_data(data.as_slice()) + parse_execute_response_data(data.as_slice()) .map_err(|e| StdError::generic_err(e.to_string()))? - .data; - } + .data + }; if let Some(data) = parsed_data { Ok(res.set_data(data)) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 8182bc3c4..fc04787fe 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -5,7 +5,7 @@ use std::ops::Deref; use cosmwasm_std::{ to_binary, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, ContractInfoResponse, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, Order, Querier, - QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgExecutionResponse, + QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgResponse, SubMsgResult, TransactionInfo, WasmMsg, WasmQuery, }; use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; @@ -436,7 +436,7 @@ where if matches!(reply_on, ReplyOn::Always | ReplyOn::Success) { let reply = Reply { id, - result: SubMsgResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgResponse { events: r.events.clone(), data: r.data, }), diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 2ee04233a..260baf0e7 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -185,8 +185,7 @@ where max.map(|b| b.to_raw_bound()), order, ) - .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))) - .flatten(); + .flat_map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))); Box::new(mapped) } } diff --git a/packages/utils/src/parse_reply.rs b/packages/utils/src/parse_reply.rs index 3b61f7474..468053de2 100644 --- a/packages/utils/src/parse_reply.rs +++ b/packages/utils/src/parse_reply.rs @@ -168,7 +168,7 @@ pub enum ParseReplyError { mod test { use super::*; use crate::parse_reply::ParseReplyError::{BrokenUtf8, ParseFailure}; - use cosmwasm_std::{SubMsgExecutionResponse, SubMsgResult}; + use cosmwasm_std::{SubMsgResponse, SubMsgResult}; use prost::Message; use std::str::from_utf8; @@ -466,7 +466,7 @@ mod test { // Build reply message let msg = Reply { id: 1, - result: SubMsgResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgResponse { events: vec![], data: Some(encoded_instantiate_reply.into()), }), @@ -514,7 +514,7 @@ mod test { // Build reply message let msg = Reply { id: 1, - result: SubMsgResult::Ok(SubMsgExecutionResponse { + result: SubMsgResult::Ok(SubMsgResponse { events: vec![], data: Some(encoded_execute_reply.into()), }), From 9221b83b5eb22389edf946938e2d9a44b6561231 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 19:18:32 +0200 Subject: [PATCH 330/631] Update packages to cw 1.0.0 --- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 4 ++-- packages/cw1155/Cargo.toml | 4 ++-- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 4 ++-- packages/cw3/Cargo.toml | 4 ++-- packages/cw4/Cargo.toml | 4 ++-- packages/multi-test/Cargo.toml | 4 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index ed8607745..e02f1bba8 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } cw-utils = { path = "../utils", version = "0.13.2" } cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } schemars = "0.8.1" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index f3584ce5b..d226895b2 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 2ce6796aa..65cc9b28b 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 5b0ea1997..77c0c9a20 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0-beta8", default-features = false } +cosmwasm-std = { version = "1.0.0", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 353ab8d9b..58031bfca 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 6a9d45b41..40d39266f 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 9d9c972bb..edb857543 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -11,9 +11,9 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 82505a7ba..d52788b8b 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,8 +20,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2"} -cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0", features = ["staking"] } +cosmwasm-storage = { version = "1.0.0" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 6656060d1..77dbcde21 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -18,7 +18,7 @@ iterator = ["cosmwasm-std/iterator"] bench = false [dependencies] -cosmwasm-std = { version = "1.0.0-beta8", default-features = false } +cosmwasm-std = { version = "1.0.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 26e25d475..496bdfa71 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } From 1659f50c38ab22e34712e275c7c985c4b3424af5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 19:24:24 +0200 Subject: [PATCH 331/631] Update contracts to cw 1.0.0 --- contracts/cw1-subkeys/Cargo.toml | 4 ++-- contracts/cw1-whitelist-ng/Cargo.toml | 4 ++-- contracts/cw1-whitelist/Cargo.toml | 4 ++-- contracts/cw1155-base/Cargo.toml | 4 ++-- contracts/cw20-base/Cargo.toml | 4 ++-- contracts/cw20-ics20/Cargo.toml | 4 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 4 ++-- contracts/cw3-flex-multisig/Cargo.toml | 4 ++-- contracts/cw4-group/Cargo.toml | 4 ++-- contracts/cw4-stake/Cargo.toml | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 1e10ab7ea..7a602761c 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -23,7 +23,7 @@ cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw1 = { path = "../../packages/cw1", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library"] } -cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cosmwasm-std = { version = "1.0.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 55eee448a..70c71b715 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -25,7 +25,7 @@ multitest = ["cw-multi-test", "anyhow"] cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw1 = { path = "../../packages/cw1", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cosmwasm-std = { version = "1.0.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -36,6 +36,6 @@ anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index f9b549856..52330ed9a 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw1 = { path = "../../packages/cw1", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } +cosmwasm-std = { version = "1.0.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index b003fad9c..65668aad7 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw1155 = { path = "../../packages/cw1155", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index b82698eb4..a67e07a57 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -22,10 +22,10 @@ cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw20 = { path = "../../packages/cw20", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 74c101605..4681ead22 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -21,7 +21,7 @@ library = [] cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw20 = { path = "../../packages/cw20", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8", features = ["stargate"] } +cosmwasm-std = { version = "1.0.0", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } schemars = "0.8.1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index fab4ea012..a11fc3a72 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -22,13 +22,13 @@ cw-utils = { path = "../../packages/utils", version = "0.13.2" } cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw3 = { path = "../../packages/cw3", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "0.13.2" } cw20-base = { path = "../cw20-base", version = "0.13.2", features = ["library"] } cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 16039cb72..8207a6486 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -24,12 +24,12 @@ cw3 = { path = "../../packages/cw3", version = "0.13.2" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.2", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } cw4-group = { path = "../cw4-group", version = "0.13.2" } cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index a1b7e07ef..d1394af6b 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -31,10 +31,10 @@ cw2 = { path = "../../packages/cw2", version = "0.13.2" } cw4 = { path = "../../packages/cw4", version = "0.13.2" } cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index c0dfb9286..c2e95e166 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -32,10 +32,10 @@ cw4 = { path = "../../packages/cw4", version = "0.13.2" } cw20 = { path = "../../packages/cw20", version = "0.13.2" } cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cosmwasm-std = { version = "1.0.0-beta8" } +cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta8" } +cosmwasm-schema = { version = "1.0.0" } From f42a661fefbeb796f40aa30f1c315959b7cdccea Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 19:24:45 +0200 Subject: [PATCH 332/631] Update optimizer in CI to latest version --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f62325e34..48b96f542 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -741,7 +741,7 @@ jobs: - run: name: Build development contracts command: | - docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.4 + docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.6 docker cp with_code:/code/artifacts ./artifacts - run: name: Show data From 58dbf80cc426d1c16e9aea436d5e5daf3a709d1b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 20:40:34 +0200 Subject: [PATCH 333/631] Allow untracked files when set version --- scripts/set_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/set_version.sh b/scripts/set_version.sh index 019b8125d..dec6b8483 100755 --- a/scripts/set_version.sh +++ b/scripts/set_version.sh @@ -21,7 +21,7 @@ if [[ "$(realpath "$SCRIPT_DIR/..")" != "$(pwd)" ]]; then fi # Ensure repo is not dirty -CHANGES_IN_REPO=$(git status --porcelain) +CHANGES_IN_REPO=$(git status --porcelain --untracked-files=no) if [[ -n "$CHANGES_IN_REPO" ]]; then echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" git status && git --no-pager diff From fccf2aac1f5efd93231b99c5e1186bbe51bbf38d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 20:41:10 +0200 Subject: [PATCH 334/631] Set version: 0.13.3 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df3eb49ec..877c40ec4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,7 +379,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -391,7 +391,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.2" +version = "0.13.3" dependencies = [ "anyhow", "cosmwasm-std", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-std", "criterion", @@ -419,7 +419,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -431,7 +431,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -441,7 +441,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -458,7 +458,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.13.2" +version = "0.13.3" dependencies = [ "anyhow", "assert_matches", @@ -477,7 +477,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.13.2" +version = "0.13.3" dependencies = [ "anyhow", "assert_matches", @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -507,7 +507,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -522,7 +522,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -558,7 +558,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -575,7 +575,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -586,7 +586,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -604,7 +604,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -623,7 +623,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -650,7 +650,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.13.2" +version = "0.13.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 7a602761c..2b2fa7eba 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw1 = { path = "../../packages/cw1", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw1 = { path = "../../packages/cw1", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.3", features = ["library"] } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.2", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.3", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 70c71b715..7b3deabcc 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.13.2" +version = "0.13.3" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw1 = { path = "../../packages/cw1", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw1 = { path = "../../packages/cw1", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 52330ed9a..d74ec2518 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw1 = { path = "../../packages/cw1", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw1 = { path = "../../packages/cw1", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 65668aad7..469c6aadb 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.13.2" +version = "0.13.3" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw1155 = { path = "../../packages/cw1155", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw1155 = { path = "../../packages/cw1155", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index a67e07a57..e3407710f 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw20 = { path = "../../packages/cw20", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw20 = { path = "../../packages/cw20", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 4681ead22..c0eca3987 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw20 = { path = "../../packages/cw20", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw20 = { path = "../../packages/cw20", version = "0.13.3" } cosmwasm-std = { version = "1.0.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index a11fc3a72..ce512afaa 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw3 = { path = "../../packages/cw3", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw3 = { path = "../../packages/cw3", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.2" } -cw20-base = { path = "../cw20-base", version = "0.13.2", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } +cw20 = { path = "../../packages/cw20", version = "0.13.3" } +cw20-base = { path = "../cw20-base", version = "0.13.3", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 8207a6486..3a1fdc66d 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw3 = { path = "../../packages/cw3", version = "0.13.2" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.2", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw3 = { path = "../../packages/cw3", version = "0.13.3" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.3", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw4-group = { path = "../cw4-group", version = "0.13.2" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.2" } +cw4-group = { path = "../cw4-group", version = "0.13.3" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index d1394af6b..e5f3912fc 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw4 = { path = "../../packages/cw4", version = "0.13.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw4 = { path = "../../packages/cw4", version = "0.13.3" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index c2e95e166..aea5ea04d 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw2 = { path = "../../packages/cw2", version = "0.13.2" } -cw4 = { path = "../../packages/cw4", version = "0.13.2" } -cw20 = { path = "../../packages/cw20", version = "0.13.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw4 = { path = "../../packages/cw4", version = "0.13.3" } +cw20 = { path = "../../packages/cw20", version = "0.13.3" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index e02f1bba8..c6a9a4919 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } -cw-utils = { path = "../utils", version = "0.13.2" } -cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } +cw-utils = { path = "../utils", version = "0.13.3" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index d226895b2..9052d22d4 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 65cc9b28b..4f0bebe75 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.13.2" +version = "0.13.3" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 77c0c9a20..4f5be5cd9 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 58031bfca..93f9f9c7a 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 40d39266f..689817e1e 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } +cw-utils = { path = "../../packages/utils", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index edb857543..2dcc39772 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.3" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index d52788b8b..89fe38550 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2"} +cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3"} cosmwasm-std = { version = "1.0.0", features = ["staking"] } cosmwasm-storage = { version = "1.0.0" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 77dbcde21..eb3fe602d 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 496bdfa71..1931df61e 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.13.2" +version = "0.13.3" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } prost = "0.9" From aa285415126943e11dbfc1e8d8a91c3e51eb0b1e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 20:41:32 +0200 Subject: [PATCH 335/631] Update CHANGELOG --- CHANGELOG.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d514dad..43ac66798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,47 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.1...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.3...HEAD) + +## [v0.13.3](https://github.com/CosmWasm/cw-plus/tree/v0.13.3) (2022-06-01) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.2...v0.13.3) + +**Closed issues:** + +- Add code coverage tooling to the CI [\#172](https://github.com/CosmWasm/cw-plus/issues/172) + +**Merged pull requests:** + +- Repo reclippization [\#721](https://github.com/CosmWasm/cw-plus/pull/721) ([hashedone](https://github.com/hashedone)) +- Add code coverage to CI [\#715](https://github.com/CosmWasm/cw-plus/pull/715) ([maurolacy](https://github.com/maurolacy)) +- Update item.rs: typo [\#713](https://github.com/CosmWasm/cw-plus/pull/713) ([rtviii](https://github.com/rtviii)) +- Update link to new shared CosmWasm SECURITY.md [\#701](https://github.com/CosmWasm/cw-plus/pull/701) ([webmaster128](https://github.com/webmaster128)) +- Add existence checking to indexed map [\#700](https://github.com/CosmWasm/cw-plus/pull/700) ([shanev](https://github.com/shanev)) + +**Closed issues:** + +- error: could not compile `ff` when running cargo test on cw20-base contract [\#714](https://github.com/CosmWasm/cw-plus/issues/714) + +## [v0.13.2](https://github.com/CosmWasm/cw-plus/tree/v0.13.2) (2022-04-11) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.1...v0.13.2) + +**Closed issues:** + +- `KeyDeserialize` trait is private making custom keys and generics over keys not possible. [\#691](https://github.com/CosmWasm/cw-plus/issues/691) +- unresolved import cosmwasm\_std::testing [\#681](https://github.com/CosmWasm/cw-plus/issues/681) +- Add non-owned `range_de` [\#463](https://github.com/CosmWasm/cw-plus/issues/463) + +**Merged pull requests:** + +- Upgrade all contracts and packages to cosmwasm-std beta8 [\#699](https://github.com/CosmWasm/cw-plus/pull/699) ([the-frey](https://github.com/the-frey)) +- Remove dead links [\#698](https://github.com/CosmWasm/cw-plus/pull/698) ([Psyf](https://github.com/Psyf)) +- cw20-ics20: fix missing assert [\#697](https://github.com/CosmWasm/cw-plus/pull/697) ([giansalex](https://github.com/giansalex)) +- storage-plus: Implement u128 key [\#694](https://github.com/CosmWasm/cw-plus/pull/694) ([orkunkl](https://github.com/orkunkl)) +- Make `KeyDeserialize` trait public [\#692](https://github.com/CosmWasm/cw-plus/pull/692) ([maurolacy](https://github.com/maurolacy)) +- Typo in QueryMsg::DownloadLogo description [\#690](https://github.com/CosmWasm/cw-plus/pull/690) ([nnoln](https://github.com/nnoln)) +- Fix publish.sh help / args [\#689](https://github.com/CosmWasm/cw-plus/pull/689) ([maurolacy](https://github.com/maurolacy)) ## [v0.13.1](https://github.com/CosmWasm/cw-plus/tree/v0.13.1) (2022-03-25) From 4ca2f33a93f6ca4139bbaf63743ee02318506a53 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 1 Jun 2022 21:08:37 +0200 Subject: [PATCH 336/631] Update migrate version --- contracts/cw20-ics20/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index bcb71733c..ce48726af 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -204,7 +204,7 @@ pub fn execute_allow( const MIGRATE_MIN_VERSION: &str = "0.11.1"; const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; -const MIGRATE_VERSION_3: &str = "0.13.2"; +const MIGRATE_VERSION_3: &str = "0.13.3"; #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { From 9dcd0c2d29f2022e4b9ea1b7db68b0e8e2a98162 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Jun 2022 12:09:55 +0200 Subject: [PATCH 337/631] Add dump_wasm_raw to App --- packages/multi-test/src/app.rs | 8 +- packages/multi-test/src/wasm.rs | 145 +++++++++++++++++--------------- 2 files changed, 82 insertions(+), 71 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 24f9be992..57db2fba8 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -5,7 +5,8 @@ use anyhow::Result as AnyResult; use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{ from_slice, to_binary, Addr, Api, Binary, BlockInfo, ContractResult, CustomQuery, Empty, - Querier, QuerierResult, QuerierWrapper, QueryRequest, Storage, SystemError, SystemResult, + Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, Storage, SystemError, + SystemResult, }; use schemars::JsonSchema; use serde::de::DeserializeOwned; @@ -565,6 +566,11 @@ where pub fn contract_data(&self, address: &Addr) -> AnyResult { self.read_module(|router, _, storage| router.wasm.load_contract(storage, address)) } + + /// This gets a raw state dump of all key-values held by a given contract + pub fn dump_wasm_raw(&self, address: &Addr) -> Vec { + self.read_module(|router, _, storage| router.wasm.dump_wasm_raw(storage, address)) + } } impl diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index fc04787fe..a5c72126c 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -5,7 +5,7 @@ use std::ops::Deref; use cosmwasm_std::{ to_binary, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, ContractInfoResponse, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, Order, Querier, - QuerierWrapper, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgResponse, + QuerierWrapper, Record, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgResponse, SubMsgResult, TransactionInfo, WasmMsg, WasmQuery, }; use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; @@ -191,6 +191,80 @@ impl WasmKeeper { .load(&prefixed_read(storage, NAMESPACE_WASM), address) .map_err(Into::into) } + + pub fn dump_wasm_raw(&self, storage: &dyn Storage, address: &Addr) -> Vec { + let storage = self.contract_storage_readonly(storage, address); + storage.range(None, None, Order::Ascending).collect() + } + + fn contract_namespace(&self, contract: &Addr) -> Vec { + let mut name = b"contract_data/".to_vec(); + name.extend_from_slice(contract.as_bytes()); + name + } + + fn contract_storage<'a>( + &self, + storage: &'a mut dyn Storage, + address: &Addr, + ) -> Box { + // We double-namespace this, once from global storage -> wasm_storage + // then from wasm_storage -> the contracts subspace + let namespace = self.contract_namespace(address); + let storage = PrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); + Box::new(storage) + } + + // fails RUNTIME if you try to write. please don't + fn contract_storage_readonly<'a>( + &self, + storage: &'a dyn Storage, + address: &Addr, + ) -> Box { + // We double-namespace this, once from global storage -> wasm_storage + // then from wasm_storage -> the contracts subspace + let namespace = self.contract_namespace(address); + let storage = ReadonlyPrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); + Box::new(storage) + } + + fn verify_attributes(attributes: &[Attribute]) -> AnyResult<()> { + for attr in attributes { + let key = attr.key.trim(); + let val = attr.value.trim(); + + if key.is_empty() { + bail!(Error::empty_attribute_key(val)); + } + + if val.is_empty() { + bail!(Error::empty_attribute_value(key)); + } + + if key.starts_with('_') { + bail!(Error::reserved_attribute_key(key)); + } + } + + Ok(()) + } + + fn verify_response(response: Response) -> AnyResult> + where + T: Clone + fmt::Debug + PartialEq + JsonSchema, + { + Self::verify_attributes(&response.attributes)?; + + for event in &response.events { + Self::verify_attributes(&event.attributes)?; + let ty = event.ty.trim(); + if ty.len() < 2 { + bail!(Error::event_type_too_short(ty)); + } + } + + Ok(response) + } } impl WasmKeeper @@ -782,75 +856,6 @@ where // it is lowercase to be compatible with the MockApi implementation of cosmwasm-std >= 1.0.0-beta8 Addr::unchecked(format!("contract{}", count)) } - - fn contract_namespace(&self, contract: &Addr) -> Vec { - let mut name = b"contract_data/".to_vec(); - name.extend_from_slice(contract.as_bytes()); - name - } - - fn contract_storage<'a>( - &self, - storage: &'a mut dyn Storage, - address: &Addr, - ) -> Box { - // We double-namespace this, once from global storage -> wasm_storage - // then from wasm_storage -> the contracts subspace - let namespace = self.contract_namespace(address); - let storage = PrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); - Box::new(storage) - } - - // fails RUNTIME if you try to write. please don't - fn contract_storage_readonly<'a>( - &self, - storage: &'a dyn Storage, - address: &Addr, - ) -> Box { - // We double-namespace this, once from global storage -> wasm_storage - // then from wasm_storage -> the contracts subspace - let namespace = self.contract_namespace(address); - let storage = ReadonlyPrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); - Box::new(storage) - } - - fn verify_attributes(attributes: &[Attribute]) -> AnyResult<()> { - for attr in attributes { - let key = attr.key.trim(); - let val = attr.value.trim(); - - if key.is_empty() { - bail!(Error::empty_attribute_key(val)); - } - - if val.is_empty() { - bail!(Error::empty_attribute_value(key)); - } - - if key.starts_with('_') { - bail!(Error::reserved_attribute_key(key)); - } - } - - Ok(()) - } - - fn verify_response(response: Response) -> AnyResult> - where - T: Clone + fmt::Debug + PartialEq + JsonSchema, - { - Self::verify_attributes(&response.attributes)?; - - for event in &response.events { - Self::verify_attributes(&event.attributes)?; - let ty = event.ty.trim(); - if ty.len() < 2 { - bail!(Error::event_type_too_short(ty)); - } - } - - Ok(response) - } } // TODO: replace with code in utils From 7f86a66fb70bd6f0e8f4051c33cf7c9602666558 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Jun 2022 12:20:14 +0200 Subject: [PATCH 338/631] Add test for dump_wasm_raw --- packages/multi-test/src/wasm.rs | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index a5c72126c..42c350ffe 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -1055,6 +1055,57 @@ mod test { assert_eq!(expected, from_slice(&info).unwrap()); } + #[test] + fn can_dump_raw_wasm_state() { + let api = MockApi::default(); + let mut keeper = WasmKeeper::::new(); + let block = mock_env().block; + let code_id = keeper.store_code(payout::contract()); + + let mut wasm_storage = MockStorage::new(); + + let contract_addr = keeper + .register_contract( + &mut wasm_storage, + code_id, + Addr::unchecked("foobar"), + Addr::unchecked("admin"), + "label".to_owned(), + 1000, + ) + .unwrap(); + + // make a contract with state + let payout = coin(1500, "mlg"); + let msg = payout::InstantiateMessage { + payout: payout.clone(), + }; + keeper + .call_instantiate( + contract_addr.clone(), + &api, + &mut wasm_storage, + &mock_router(), + &block, + mock_info("foobar", &[]), + to_vec(&msg).unwrap(), + ) + .unwrap(); + + // dump state + let state = keeper.dump_wasm_raw(&wasm_storage, &contract_addr); + assert_eq!(state.len(), 2); + // check contents + let (k, v) = &state[0]; + assert_eq!(k.as_slice(), b"count"); + let count: u32 = from_slice(v).unwrap(); + assert_eq!(count, 1); + let (k, v) = &state[1]; + assert_eq!(k.as_slice(), b"payout"); + let stored_pay: payout::InstantiateMessage = from_slice(v).unwrap(); + assert_eq!(stored_pay.payout, payout); + } + #[test] fn contract_send_coins() { let api = MockApi::default(); From fc089febdab836400982eb096a545997a2bf4aed Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 2 Jun 2022 12:41:36 +0200 Subject: [PATCH 339/631] Set version: 0.13.4 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 10 +++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 +-- 21 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 877c40ec4..b7cb3c849 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,7 +379,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -391,7 +391,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.3" +version = "0.13.4" dependencies = [ "anyhow", "cosmwasm-std", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-std", "criterion", @@ -419,7 +419,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -431,7 +431,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -441,7 +441,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -458,7 +458,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.13.3" +version = "0.13.4" dependencies = [ "anyhow", "assert_matches", @@ -477,7 +477,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.13.3" +version = "0.13.4" dependencies = [ "anyhow", "assert_matches", @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -507,7 +507,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -522,7 +522,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -558,7 +558,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -575,7 +575,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -586,7 +586,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -604,7 +604,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -623,7 +623,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -650,7 +650,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.13.3" +version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 2b2fa7eba..73172f4f1 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw1 = { path = "../../packages/cw1", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.3", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw1 = { path = "../../packages/cw1", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.4", features = ["library"] } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.3", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.4", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 7b3deabcc..fc231f04e 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.13.3" +version = "0.13.4" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw1 = { path = "../../packages/cw1", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw1 = { path = "../../packages/cw1", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index d74ec2518..f1666d5fb 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw1 = { path = "../../packages/cw1", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw1 = { path = "../../packages/cw1", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 469c6aadb..f0f0534c1 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.13.3" +version = "0.13.4" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw1155 = { path = "../../packages/cw1155", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw1155 = { path = "../../packages/cw1155", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index e3407710f..19367cb8b 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw20 = { path = "../../packages/cw20", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw20 = { path = "../../packages/cw20", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index c0eca3987..c5d5a59b9 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw20 = { path = "../../packages/cw20", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw20 = { path = "../../packages/cw20", version = "0.13.4" } cosmwasm-std = { version = "1.0.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index ce512afaa..5b44bee16 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw3 = { path = "../../packages/cw3", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw3 = { path = "../../packages/cw3", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.3" } -cw20-base = { path = "../cw20-base", version = "0.13.3", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } +cw20 = { path = "../../packages/cw20", version = "0.13.4" } +cw20-base = { path = "../cw20-base", version = "0.13.4", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 3a1fdc66d..d829ae454 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw3 = { path = "../../packages/cw3", version = "0.13.3" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.3", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw3 = { path = "../../packages/cw3", version = "0.13.4" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.4", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw4-group = { path = "../cw4-group", version = "0.13.3" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.3" } +cw4-group = { path = "../cw4-group", version = "0.13.4" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index e5f3912fc..722150a1a 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw4 = { path = "../../packages/cw4", version = "0.13.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw4 = { path = "../../packages/cw4", version = "0.13.4" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index aea5ea04d..d27c1e12e 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw2 = { path = "../../packages/cw2", version = "0.13.3" } -cw4 = { path = "../../packages/cw4", version = "0.13.3" } -cw20 = { path = "../../packages/cw20", version = "0.13.3" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw4 = { path = "../../packages/cw4", version = "0.13.4" } +cw20 = { path = "../../packages/cw20", version = "0.13.4" } +cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index c6a9a4919..0b3946cf9 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } -cw-utils = { path = "../utils", version = "0.13.3" } -cw-storage-plus = { path = "../storage-plus", version = "0.13.3" } +cw-utils = { path = "../utils", version = "0.13.4" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.4" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 9052d22d4..e4506bcc9 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 4f0bebe75..d49acb9c6 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.13.3" +version = "0.13.4" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 4f5be5cd9..c240df878 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ documentation = "https://docs.cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 93f9f9c7a..8a3181632 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 689817e1e..7e585a17d 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } +cw-utils = { path = "../../packages/utils", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 2dcc39772..ff6f996fa 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 89fe38550..8a059e042 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -18,8 +18,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.3" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3"} +cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4"} cosmwasm-std = { version = "1.0.0", features = ["staking"] } cosmwasm-storage = { version = "1.0.0" } itertools = "0.10.1" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index eb3fe602d..33bff7c05 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 1931df61e..b31548e02 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.13.3" +version = "0.13.4" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -18,5 +18,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.3" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } prost = "0.9" From 404cf35ae456104175fbd70871e3d511f6590465 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 2 Jun 2022 12:43:05 +0200 Subject: [PATCH 340/631] Update CHANGELOG --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43ac66798..ecdbf257a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.3...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.4...HEAD) + +## [v0.13.4](https://github.com/CosmWasm/cw-plus/tree/v0.13.4) (2022-06-02) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.3...v0.13.4) + +**Merged pull requests:** + +- Dump state multitest [\#732](https://github.com/CosmWasm/cw-plus/pull/732) ([ethanfrey](https://github.com/ethanfrey)) ## [v0.13.3](https://github.com/CosmWasm/cw-plus/tree/v0.13.3) (2022-06-01) From c99db3a0c2deb81cb3ffc5bbe0ba3c506bc2a3ae Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 2 Jun 2022 12:48:23 +0200 Subject: [PATCH 341/631] Update migrate version for good --- contracts/cw20-ics20/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index ce48726af..07c25e14a 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -204,7 +204,7 @@ pub fn execute_allow( const MIGRATE_MIN_VERSION: &str = "0.11.1"; const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; -const MIGRATE_VERSION_3: &str = "0.13.3"; +const MIGRATE_VERSION_3: &str = CONTRACT_VERSION; #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { From 16b86925485c36bfacd0fedc514c2c5962f6a17e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 2 Jun 2022 12:54:47 +0200 Subject: [PATCH 342/631] Update check_contract to latest version in CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 48b96f542..b2f1d6858 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -602,7 +602,7 @@ jobs: - run: name: Install check_contract # Uses --debug for compilation speed - command: cargo install --debug --version 1.0.0-beta8 --features iterator --example check_contract -- cosmwasm-vm + command: cargo install --debug --version 1.0.0 --features iterator --example check_contract -- cosmwasm-vm - save_cache: paths: - /usr/local/cargo/registry From 5a8cdbe6e16fd66cfe3d43d0da7277900e5cb627 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Jun 2022 13:08:17 +0200 Subject: [PATCH 343/631] Properly fix ics20 migration tests, but patching test code not production code --- contracts/cw20-ics20/src/contract.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 07c25e14a..8d001b5ee 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -204,7 +204,8 @@ pub fn execute_allow( const MIGRATE_MIN_VERSION: &str = "0.11.1"; const MIGRATE_VERSION_2: &str = "0.12.0-alpha1"; -const MIGRATE_VERSION_3: &str = CONTRACT_VERSION; +// the new functionality starts in 0.13.1, this is the last release that needs to be migrated to v3 +const MIGRATE_VERSION_3: &str = "0.13.0"; #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { @@ -575,6 +576,8 @@ mod test { // balances set high deps.querier .update_balance(MOCK_CONTRACT_ADDR, coins(50000, native)); + // pretend this is an old contract - set version explicitly + set_contract_version(deps.as_mut().storage, CONTRACT_NAME, MIGRATE_VERSION_3).unwrap(); // channel state a bit lower (some in-flight acks) let state = ChannelState { From deef1df68c7d34bb917bf0dc09c2cc1eee7e4532 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 7 Jun 2022 10:13:52 +0200 Subject: [PATCH 344/631] Use standard CosmosMsg --- packages/multi-test/src/app.rs | 7 +- packages/multi-test/src/lib.rs | 1 - packages/multi-test/src/untyped_msg.rs | 95 -------------------------- 3 files changed, 4 insertions(+), 99 deletions(-) delete mode 100644 packages/multi-test/src/untyped_msg.rs diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 57db2fba8..ac5fe558d 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -1,11 +1,12 @@ use std::fmt::{self, Debug}; use std::marker::PhantomData; +use anyhow::bail; use anyhow::Result as AnyResult; use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{ - from_slice, to_binary, Addr, Api, Binary, BlockInfo, ContractResult, CustomQuery, Empty, - Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, Storage, SystemError, + from_slice, to_binary, Addr, Api, Binary, BlockInfo, ContractResult, CosmosMsg, CustomQuery, + Empty, Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, Storage, SystemError, SystemResult, }; use schemars::JsonSchema; @@ -18,7 +19,6 @@ use crate::executor::{AppResponse, Executor}; use crate::module::{FailingModule, Module}; use crate::staking::{Distribution, FailingDistribution, FailingStaking, Staking, StakingSudo}; use crate::transactions::transactional; -use crate::untyped_msg::CosmosMsg; use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo}; pub fn next_block(block: &mut BlockInfo) { @@ -799,6 +799,7 @@ where CosmosMsg::Distribution(msg) => self .distribution .execute(api, storage, self, block, sender, msg), + _ => bail!("Cannot execute {:?}", msg), } } diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 543f07d3a..b532a8152 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -17,7 +17,6 @@ mod module; mod staking; mod test_helpers; mod transactions; -mod untyped_msg; mod wasm; pub use crate::app::{ diff --git a/packages/multi-test/src/untyped_msg.rs b/packages/multi-test/src/untyped_msg.rs deleted file mode 100644 index 9e857fdcb..000000000 --- a/packages/multi-test/src/untyped_msg.rs +++ /dev/null @@ -1,95 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt; - -use cosmwasm_std::{BankMsg, DistributionMsg, Empty, StakingMsg, WasmMsg}; - -/// This is needed so we can embed CosmosMsg as a trait bound. -/// See https://github.com/CosmWasm/cosmwasm/pull/1098 for a proper solution -/// (when we can deprecate this one) -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum CosmosMsg { - Bank(BankMsg), - // by default we use RawMsg, but a contract can override that - // to call into more app-specific code (whatever they define) - Custom(T), - #[cfg(feature = "staking")] - Distribution(DistributionMsg), - #[cfg(feature = "staking")] - Staking(StakingMsg), - Wasm(WasmMsg), -} - -impl From> for cosmwasm_std::CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(input: CosmosMsg) -> Self { - match input { - CosmosMsg::Bank(b) => cosmwasm_std::CosmosMsg::Bank(b), - CosmosMsg::Custom(c) => cosmwasm_std::CosmosMsg::Custom(c), - #[cfg(feature = "staking")] - CosmosMsg::Distribution(d) => cosmwasm_std::CosmosMsg::Distribution(d), - #[cfg(feature = "staking")] - CosmosMsg::Staking(s) => cosmwasm_std::CosmosMsg::Staking(s), - CosmosMsg::Wasm(w) => cosmwasm_std::CosmosMsg::Wasm(w), - } - } -} - -impl From> for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(input: cosmwasm_std::CosmosMsg) -> CosmosMsg { - match input { - cosmwasm_std::CosmosMsg::Bank(b) => CosmosMsg::Bank(b), - cosmwasm_std::CosmosMsg::Custom(c) => CosmosMsg::Custom(c), - #[cfg(feature = "staking")] - cosmwasm_std::CosmosMsg::Distribution(d) => CosmosMsg::Distribution(d), - #[cfg(feature = "staking")] - cosmwasm_std::CosmosMsg::Staking(s) => CosmosMsg::Staking(s), - cosmwasm_std::CosmosMsg::Wasm(w) => CosmosMsg::Wasm(w), - _ => panic!("Unsupported type"), - } - } -} - -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(msg: BankMsg) -> Self { - CosmosMsg::Bank(msg) - } -} - -#[cfg(feature = "staking")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(msg: StakingMsg) -> Self { - CosmosMsg::Staking(msg) - } -} - -#[cfg(feature = "staking")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(msg: DistributionMsg) -> Self { - CosmosMsg::Distribution(msg) - } -} - -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - fn from(msg: WasmMsg) -> Self { - CosmosMsg::Wasm(msg) - } -} From aef5e80fe8c1677129e35e259fba84da6b8b8a90 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 7 Jun 2022 10:26:08 +0200 Subject: [PATCH 345/631] Fix clippy warnings --- packages/multi-test/src/app.rs | 4 ++-- packages/multi-test/src/wasm.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index ac5fe558d..68995265c 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -627,7 +627,7 @@ where transactional(&mut *storage, |write_cache, _| { msgs.into_iter() - .map(|msg| router.execute(&*api, write_cache, block, sender.clone(), msg.into())) + .map(|msg| router.execute(&*api, write_cache, block, sender.clone(), msg)) .collect() }) } @@ -1499,7 +1499,7 @@ mod test { lucky_winner: winner.clone(), runner_up: second.clone(), }); - app.execute(Addr::unchecked("anyone"), msg.into()).unwrap(); + app.execute(Addr::unchecked("anyone"), msg).unwrap(); // see if coins were properly added let big_win = app.wrap().query_balance(&winner, denom).unwrap(); diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 42c350ffe..cdbd06143 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -320,7 +320,7 @@ where amount: amount.to_vec(), } .into(); - let res = router.execute(api, storage, block, sender.into(), msg.into())?; + let res = router.execute(api, storage, block, sender.into(), msg)?; Ok(res) } else { Ok(AppResponse::default()) @@ -502,7 +502,7 @@ where // execute in cache let res = transactional(storage, |write_cache, _| { - router.execute(api, write_cache, block, contract.clone(), msg.into()) + router.execute(api, write_cache, block, contract.clone(), msg) }); // call reply if meaningful From 8f91cf61dea67e4f982f2ec590d52a9aee2ec08c Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 13 Jun 2022 15:19:03 +0200 Subject: [PATCH 346/631] README: bump workspace-optimizer version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd56c7cae..bcb3e607e 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.4 + cosmwasm/workspace-optimizer:0.12.6 ``` This will compile all packages in the `contracts` directory and output the From be477f395dc0566559f00bb81898649d5a852733 Mon Sep 17 00:00:00 2001 From: Janita Chalam Date: Mon, 30 May 2022 15:49:25 -0700 Subject: [PATCH 347/631] add execute msg to update minter --- contracts/cw20-base/src/contract.rs | 73 +++++++++++++++++++++++++++++ packages/cw20/src/msg.rs | 2 + 2 files changed, 75 insertions(+) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 72f7b3d53..145812ea8 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -225,6 +225,9 @@ pub fn execute( marketing, } => execute_update_marketing(deps, env, info, project, description, marketing), ExecuteMsg::UploadLogo(logo) => execute_upload_logo(deps, env, info, logo), + ExecuteMsg::UpdateMinter { new_minter } => { + execute_update_minter(deps, env, info, new_minter) + } } } @@ -377,6 +380,32 @@ pub fn execute_send( Ok(res) } +pub fn execute_update_minter( + deps: DepsMut, + _env: Env, + info: MessageInfo, + new_minter: String, +) -> Result { + let mut config = TOKEN_INFO.load(deps.storage)?; + // Check that sender is authorized to update minter + if config.mint.is_none() || config.mint.as_ref().unwrap().minter != info.sender { + return Err(ContractError::Unauthorized {}); + } + + let minter = deps.api.addr_validate(&new_minter)?; + let minter_data = MinterData { + minter, + cap: config.mint.unwrap().cap, + }; + config.mint = Some(minter_data); + + TOKEN_INFO.save(deps.storage, &config)?; + + Ok(Response::default() + .add_attribute("action", "update_minter") + .add_attribute("minter", new_minter)) +} + pub fn execute_update_marketing( deps: DepsMut, _env: Env, @@ -871,6 +900,50 @@ mod tests { assert_eq!(err, ContractError::Unauthorized {}); } + #[test] + fn minter_can_update_itself() { + let mut deps = mock_dependencies(); + let minter = String::from("minter"); + do_instantiate_with_minter( + deps.as_mut(), + &String::from("genesis"), + Uint128::new(1234), + &minter, + None, + ); + + let msg = ExecuteMsg::UpdateMinter { + new_minter: String::from("new_minter"), + }; + + let info = mock_info(&minter, &[]); + let env = mock_env(); + let res = execute(deps.as_mut(), env, info, msg); + assert!(res.is_ok()); + } + + #[test] + fn others_cannot_update_minter() { + let mut deps = mock_dependencies(); + let minter = String::from("minter"); + do_instantiate_with_minter( + deps.as_mut(), + &String::from("genesis"), + Uint128::new(1234), + &minter, + None, + ); + + let msg = ExecuteMsg::UpdateMinter { + new_minter: String::from("new_minter"), + }; + + let info = mock_info("not the minter", &[]); + let env = mock_env(); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); + } + #[test] fn no_one_mints_if_minter_unset() { let mut deps = mock_dependencies(); diff --git a/packages/cw20/src/msg.rs b/packages/cw20/src/msg.rs index 4a7518b54..4cd6fba63 100644 --- a/packages/cw20/src/msg.rs +++ b/packages/cw20/src/msg.rs @@ -55,6 +55,8 @@ pub enum Cw20ExecuteMsg { /// Only with the "mintable" extension. If authorized, creates amount new tokens /// and adds to the recipient balance. Mint { recipient: String, amount: Uint128 }, + /// Only with the "mintable" extension. The current minter may set a new minter. + UpdateMinter { new_minter: String }, /// Only with the "marketing" extension. If authorized, updates marketing metadata. /// Setting None/null for any of these will leave it unchanged. /// Setting Some("") will clear this field on the contract storage From 0a6546bc3fb3b337d34a47bf4763c677520ea44a Mon Sep 17 00:00:00 2001 From: Janita Chalam Date: Wed, 8 Jun 2022 09:48:26 -0700 Subject: [PATCH 348/631] resolve comments --- contracts/cw20-base/src/contract.rs | 43 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 145812ea8..2bdf482cb 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -307,8 +307,17 @@ pub fn execute_mint( return Err(ContractError::InvalidZeroAmount {}); } - let mut config = TOKEN_INFO.load(deps.storage)?; - if config.mint.is_none() || config.mint.as_ref().unwrap().minter != info.sender { + let mut config = TOKEN_INFO + .may_load(deps.storage)? + .ok_or(ContractError::Unauthorized {})?; + + if config + .mint + .as_ref() + .ok_or(ContractError::Unauthorized {})? + .minter + != info.sender + { return Err(ContractError::Unauthorized {}); } @@ -386,16 +395,19 @@ pub fn execute_update_minter( info: MessageInfo, new_minter: String, ) -> Result { - let mut config = TOKEN_INFO.load(deps.storage)?; - // Check that sender is authorized to update minter - if config.mint.is_none() || config.mint.as_ref().unwrap().minter != info.sender { + let mut config = TOKEN_INFO + .may_load(deps.storage)? + .ok_or(ContractError::Unauthorized {})?; + + let mint = config.mint.as_ref().ok_or(ContractError::Unauthorized {})?; + if mint.minter != info.sender { return Err(ContractError::Unauthorized {}); } let minter = deps.api.addr_validate(&new_minter)?; let minter_data = MinterData { minter, - cap: config.mint.unwrap().cap, + cap: mint.cap, }; config.mint = Some(minter_data); @@ -403,7 +415,7 @@ pub fn execute_update_minter( Ok(Response::default() .add_attribute("action", "update_minter") - .add_attribute("minter", new_minter)) + .add_attribute("new_minter", new_minter)) } pub fn execute_update_marketing( @@ -901,25 +913,34 @@ mod tests { } #[test] - fn minter_can_update_itself() { + fn minter_can_update_minter_but_not_cap() { let mut deps = mock_dependencies(); let minter = String::from("minter"); + let cap = Some(Uint128::from(3000000u128)); do_instantiate_with_minter( deps.as_mut(), &String::from("genesis"), Uint128::new(1234), &minter, - None, + cap, ); + let new_minter = "new_minter"; let msg = ExecuteMsg::UpdateMinter { - new_minter: String::from("new_minter"), + new_minter: new_minter.to_string(), }; let info = mock_info(&minter, &[]); let env = mock_env(); - let res = execute(deps.as_mut(), env, info, msg); + let res = execute(deps.as_mut(), env.clone(), info, msg); assert!(res.is_ok()); + let query_minter_msg = QueryMsg::Minter {}; + let res = query(deps.as_ref(), env, query_minter_msg); + let mint: MinterResponse = from_binary(&res.unwrap()).unwrap(); + + // Minter cannot update cap. + assert!(mint.cap == cap); + assert!(mint.minter == new_minter) } #[test] From c154dc3c4a43bc82db747b0ab606ac20c5b233dd Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sat, 18 Jun 2022 12:11:04 +0200 Subject: [PATCH 349/631] cw3-flex: Add implementation for optional executor --- contracts/cw3-flex-multisig/src/contract.rs | 24 +++++++++++++++++++-- contracts/cw3-flex-multisig/src/msg.rs | 5 +++++ contracts/cw3-flex-multisig/src/state.rs | 13 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 5616cba7d..7bc0978c1 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -19,7 +19,7 @@ use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{Config, CONFIG}; +use crate::state::{Config, Executor, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; @@ -46,6 +46,7 @@ pub fn instantiate( threshold: msg.threshold, max_voting_period: msg.max_voting_period, group_addr, + executor: msg.executor, }; CONFIG.save(deps.storage, &cfg)?; @@ -192,7 +193,26 @@ pub fn execute_execute( info: MessageInfo, proposal_id: u64, ) -> Result { - // anyone can trigger this if the vote passed + let cfg = CONFIG.load(deps.storage)?; + + // Executor can be set in 3 ways: + // - Member: any member of the voting group can execute + // - Only: only passed address is able to execute + // - None: Anyone can execute message + if let Some(executor) = cfg.executor { + match executor { + Executor::Member => { + cfg.group_addr + .is_member(&deps.querier, &info.sender, None)? + .ok_or(ContractError::Unauthorized {})?; + } + Executor::Only(addr) => { + if addr != info.sender { + return Err(ContractError::Unauthorized {}); + } + } + } + } let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 8d72cd37b..99437b26b 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -6,12 +6,17 @@ use cw3::Vote; use cw4::MemberChangedHookMsg; use cw_utils::{Duration, Expiration, Threshold}; +use crate::state::Executor; + #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct InstantiateMsg { // this is the group contract that contains the member list pub group_addr: String, pub threshold: Threshold, pub max_voting_period: Duration, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, } // TODO: add some T variants? Maybe good enough as fixed Empty for now diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 023662b8b..bdbc90456 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,16 +1,29 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use cosmwasm_std::Addr; use cw4::Cw4Contract; use cw_storage_plus::Item; use cw_utils::{Duration, Threshold}; +/// Defines who is able to execute proposals once passed +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub enum Executor { + /// Any member of the voting group, even with 0 points + Member, + /// Only the given address + Only(Addr), +} + #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub struct Config { pub threshold: Threshold, pub max_voting_period: Duration, // Total weight and voters are queried from this contract pub group_addr: Cw4Contract, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, } // unique items From 57c11d65f692b4566a6bd01a7aba14ddd8a9efd3 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sat, 18 Jun 2022 12:22:20 +0200 Subject: [PATCH 350/631] cw3-flex: Adjust existing test to new executor parameter --- contracts/cw3-flex-multisig/src/contract.rs | 49 ++++++++++++++------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 7bc0978c1..111b8f2ff 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -193,12 +193,18 @@ pub fn execute_execute( info: MessageInfo, proposal_id: u64, ) -> Result { - let cfg = CONFIG.load(deps.storage)?; + let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; + // we allow execution even after the proposal "expiration" as long as all vote come in before + // that point. If it was approved on time, it can be executed any time. + if prop.current_status(&env.block) != Status::Passed { + return Err(ContractError::WrongExecuteStatus {}); + } // Executor can be set in 3 ways: // - Member: any member of the voting group can execute // - Only: only passed address is able to execute // - None: Anyone can execute message + let cfg = CONFIG.load(deps.storage)?; if let Some(executor) = cfg.executor { match executor { Executor::Member => { @@ -214,13 +220,6 @@ pub fn execute_execute( } } - let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - // we allow execution even after the proposal "expiration" as long as all vote come in before - // that point. If it was approved on time, it can be executed any time. - if prop.current_status(&env.block) != Status::Passed { - return Err(ContractError::WrongExecuteStatus {}); - } - // set it to executed prop.status = Status::Executed; PROPOSALS.save(deps.storage, proposal_id, &prop)?; @@ -517,12 +516,14 @@ mod tests { group: Addr, threshold: Threshold, max_voting_period: Duration, + executor: Option, ) -> Addr { let flex_id = app.store_code(contract_flex()); let msg = crate::msg::InstantiateMsg { group_addr: group.to_string(), threshold, max_voting_period, + executor, }; app.instantiate_contract(flex_id, Addr::unchecked(OWNER), &msg, &[], "flex", None) .unwrap() @@ -547,6 +548,7 @@ mod tests { max_voting_period, init_funds, multisig_as_group_admin, + None, ) } @@ -557,6 +559,7 @@ mod tests { max_voting_period: Duration, init_funds: Vec, multisig_as_group_admin: bool, + executor: Option, ) -> (Addr, Addr) { // 1. Instantiate group contract with members (and OWNER as admin) let members = vec![ @@ -571,7 +574,13 @@ mod tests { app.update_block(next_block); // 2. Set up Multisig backed by this group - let flex_addr = instantiate_flex(app, group_addr.clone(), threshold, max_voting_period); + let flex_addr = instantiate_flex( + app, + group_addr.clone(), + threshold, + max_voting_period, + executor, + ); app.update_block(next_block); // 3. (Optional) Set the multisig as the group owner @@ -636,6 +645,7 @@ mod tests { quorum: Decimal::percent(1), }, max_voting_period, + executor: None, }; let err = app .instantiate_contract( @@ -657,6 +667,7 @@ mod tests { group_addr: group_addr.to_string(), threshold: Threshold::AbsoluteCount { weight: 100 }, max_voting_period, + executor: None, }; let err = app .instantiate_contract( @@ -678,6 +689,7 @@ mod tests { group_addr: group_addr.to_string(), threshold: Threshold::AbsoluteCount { weight: 1 }, max_voting_period, + executor: None, }; let flex_addr = app .instantiate_contract( @@ -835,7 +847,8 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }; - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = + setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); // create proposal with 1 vote power let proposal = pay_somebody_proposal(); @@ -930,7 +943,8 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = + setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); @@ -1121,7 +1135,8 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = + setup_test_case(&mut app, threshold, voting_period, init_funds, true, None); // ensure we have cash to cover the proposal let contract_bal = app.wrap().query_balance(&flex_addr, "BTC").unwrap(); @@ -1227,6 +1242,7 @@ mod tests { Duration::Time(voting_period), init_funds, true, + None, ); // ensure we have cash to cover the proposal @@ -1302,7 +1318,8 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Height(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = + setup_test_case(&mut app, threshold, voting_period, init_funds, true, None); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); @@ -1354,7 +1371,7 @@ mod tests { }; let voting_period = Duration::Time(20000); let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); // VOTER1 starts a proposal to send some tokens (1/4 votes) let proposal = pay_somebody_proposal(); @@ -1600,7 +1617,7 @@ mod tests { }; let voting_period = Duration::Time(20000); let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); // VOTER3 starts a proposal to send some tokens (3/12 votes) let proposal = pay_somebody_proposal(); @@ -1683,6 +1700,7 @@ mod tests { voting_period, init_funds, false, + None, ); // VOTER3 starts a proposal to send some tokens (3 votes) @@ -1753,6 +1771,7 @@ mod tests { voting_period, init_funds, false, + None, ); // create proposal From 467c4725200ab4c766c9569e6fce675fecb400b3 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sat, 18 Jun 2022 13:49:14 +0200 Subject: [PATCH 351/631] cw3-flex: Add testcases that confirms executor works --- contracts/cw3-flex-multisig/src/contract.rs | 122 ++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 111b8f2ff..53e8032fd 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1226,6 +1226,128 @@ mod tests { ); } + #[test] + fn execute_with_executor_member() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(crate::state::Executor::Member), + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER2)), + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + + #[test] + fn execute_with_executor_only() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(crate::state::Executor::Only(Addr::unchecked(VOTER3))), + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked(VOTER1)), + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER3)), + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + #[test] fn proposal_pass_on_expiration() { let init_funds = coins(10, "BTC"); From ad6a88930fb873675214cb83b31162cd1136078f Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sun, 19 Jun 2022 12:17:18 +0200 Subject: [PATCH 352/631] cw3-flex: Create authorize method for Config structure --- contracts/cw3-flex-multisig/src/contract.rs | 21 ++-------------- contracts/cw3-flex-multisig/src/state.rs | 28 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 53e8032fd..4157a83c3 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -19,7 +19,7 @@ use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{Config, Executor, CONFIG}; +use crate::state::{Config, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; @@ -200,25 +200,8 @@ pub fn execute_execute( return Err(ContractError::WrongExecuteStatus {}); } - // Executor can be set in 3 ways: - // - Member: any member of the voting group can execute - // - Only: only passed address is able to execute - // - None: Anyone can execute message let cfg = CONFIG.load(deps.storage)?; - if let Some(executor) = cfg.executor { - match executor { - Executor::Member => { - cfg.group_addr - .is_member(&deps.querier, &info.sender, None)? - .ok_or(ContractError::Unauthorized {})?; - } - Executor::Only(addr) => { - if addr != info.sender { - return Err(ContractError::Unauthorized {}); - } - } - } - } + cfg.authorize(&deps.querier, &info.sender)?; // set it to executed prop.status = Status::Executed; diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index bdbc90456..721c43882 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,11 +1,13 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::Addr; +use cosmwasm_std::{Addr, QuerierWrapper}; use cw4::Cw4Contract; use cw_storage_plus::Item; use cw_utils::{Duration, Threshold}; +use crate::error::ContractError; + /// Defines who is able to execute proposals once passed #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] pub enum Executor { @@ -26,5 +28,29 @@ pub struct Config { pub executor: Option, } +impl Config { + // Executor can be set in 3 ways: + // - Member: any member of the voting group can execute + // - Only: only passed address is able to execute + // - None: Anyone can execute message + pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> { + if let Some(executor) = &self.executor { + match executor { + Executor::Member => { + self.group_addr + .is_member(querier, sender, None)? + .ok_or(ContractError::Unauthorized {})?; + } + Executor::Only(addr) => { + if addr != sender { + return Err(ContractError::Unauthorized {}); + } + } + } + } + Ok(()) + } +} + // unique items pub const CONFIG: Item = Item::new("config"); From 1e1f6e582da162b9304fd02f975ca5f7420a6fbb Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sun, 19 Jun 2022 12:23:42 +0200 Subject: [PATCH 353/631] cw3-flex: Adjust comments to match authorize methods better --- contracts/cw3-flex-multisig/src/contract.rs | 14 +++++++------- contracts/cw3-flex-multisig/src/state.rs | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 4157a83c3..79ac0fc27 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1225,7 +1225,7 @@ mod tests { voting_period, init_funds, true, - Some(crate::state::Executor::Member), + Some(crate::state::Executor::Member), // set executor as Member of voting group ); // create proposal with 0 vote power @@ -1248,7 +1248,7 @@ mod tests { let execution = ExecuteMsg::Execute { proposal_id }; let err = app .execute_contract( - Addr::unchecked(Addr::unchecked("anyone")), + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute flex_addr.clone(), &execution, &[], @@ -1257,7 +1257,7 @@ mod tests { assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); app.execute_contract( - Addr::unchecked(Addr::unchecked(VOTER2)), + Addr::unchecked(Addr::unchecked(VOTER2)), // member of voting group is allowed to execute flex_addr, &execution, &[], @@ -1281,7 +1281,7 @@ mod tests { voting_period, init_funds, true, - Some(crate::state::Executor::Only(Addr::unchecked(VOTER3))), + Some(crate::state::Executor::Only(Addr::unchecked(VOTER3))), // only VOTER3 can execute proposal ); // create proposal with 0 vote power @@ -1304,7 +1304,7 @@ mod tests { let execution = ExecuteMsg::Execute { proposal_id }; let err = app .execute_contract( - Addr::unchecked(Addr::unchecked("anyone")), + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute flex_addr.clone(), &execution, &[], @@ -1314,7 +1314,7 @@ mod tests { let err = app .execute_contract( - Addr::unchecked(Addr::unchecked(VOTER1)), + Addr::unchecked(Addr::unchecked(VOTER1)), // VOTER1 is not allowed to execute flex_addr.clone(), &execution, &[], @@ -1323,7 +1323,7 @@ mod tests { assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); app.execute_contract( - Addr::unchecked(Addr::unchecked(VOTER3)), + Addr::unchecked(Addr::unchecked(VOTER3)), // VOTER3 is allowed to execute flex_addr, &execution, &[], diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 721c43882..a1e388777 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -30,9 +30,9 @@ pub struct Config { impl Config { // Executor can be set in 3 ways: - // - Member: any member of the voting group can execute - // - Only: only passed address is able to execute - // - None: Anyone can execute message + // - Member: any member of the voting group is authorized + // - Only: only passed address is authorized + // - None: Everyone are authorized pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> { if let Some(executor) = &self.executor { match executor { From 5c1b39f68195c6b10c43529ba788d9a0746db6a3 Mon Sep 17 00:00:00 2001 From: Luke Park Date: Tue, 28 Jun 2022 22:19:06 +0900 Subject: [PATCH 354/631] fix: relocate contents --- packages/cw20/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/cw20/README.md b/packages/cw20/README.md index 970db35ff..35be5f736 100644 --- a/packages/cw20/README.md +++ b/packages/cw20/README.md @@ -144,6 +144,14 @@ the minter is a smart contract. This should be enabled with all blockchains that have iterator support. It allows us to get lists of results with pagination. +### Queries + +`AllAllowances{owner, start_after, limit}` - Returns the list of all non-expired allowances +by the given owner. `start_after` and `limit` provide pagination. + +`AllAccounts{start_after, limit}` - Returns the list of all accounts that have been created on +the contract (just the addresses). `start_after` and `limit` provide pagination. + ## Marketing This allows us to attach more metadata on the token to help with displaying the token in @@ -173,11 +181,3 @@ account, this will update some marketing-related metadata on the contract. `DownloadLogo{}` - If the token's logo was previously uploaded to the blockchain (see `UploadLogo` message), then it returns the raw data to be displayed in a browser. Return type is `DownloadLogoResponse{ mime_type, data }`. - -### Queries - -`AllAllowances{owner, start_after, limit}` - Returns the list of all non-expired allowances -by the given owner. `start_after` and `limit` provide pagination. - -`AllAccounts{start_after, limit}` - Returns the list of all accounts that have been created on -the contract (just the addresses). `start_after` and `limit` provide pagination. From d9cbf6dc035eed07d0f78559c35d0cb9e6362b70 Mon Sep 17 00:00:00 2001 From: Zeke Medley Date: Mon, 27 Jun 2022 13:21:27 -0700 Subject: [PATCH 355/631] Add migrate method to cw20 base. --- Cargo.lock | 1 + contracts/cw20-base/Cargo.toml | 1 + contracts/cw20-base/src/contract.rs | 74 ++++++++++++++++++++++++++++- contracts/cw20-base/src/msg.rs | 3 ++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b7cb3c849..50cb5c562 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -547,6 +547,7 @@ version = "0.13.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 19367cb8b..38177c403 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -29,3 +29,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 2bdf482cb..f7bd0e1f4 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -16,7 +16,7 @@ use crate::allowances::{ }; use crate::enumerable::{query_all_accounts, query_all_allowances}; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{MinterData, TokenInfo, BALANCES, LOGO, MARKETING_INFO, TOKEN_INFO}; // version info for migration info @@ -578,6 +578,11 @@ pub fn query_download_logo(deps: Deps) -> StdResult { } } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + Ok(Response::default()) +} + #[cfg(test)] mod tests { use cosmwasm_std::testing::{ @@ -1265,6 +1270,73 @@ mod tests { ); } + mod migration { + use super::*; + + use cosmwasm_std::Empty; + use cw_multi_test::{App, Contract, ContractWrapper, Executor}; + + fn cw20_contract() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ) + .with_migrate(crate::contract::migrate); + Box::new(contract) + } + + #[test] + fn test_migrate() { + let mut app = App::default(); + + let cw20_id = app.store_code(cw20_contract()); + let cw20_addr = app + .instantiate_contract( + cw20_id, + Addr::unchecked("sender"), + &InstantiateMsg { + name: "Token".to_string(), + symbol: "TOKEN".to_string(), + decimals: 6, + initial_balances: vec![Cw20Coin { + address: "sender".to_string(), + amount: Uint128::new(100), + }], + mint: None, + marketing: None, + }, + &[], + "TOKEN", + Some("sender".to_string()), + ) + .unwrap(); + + app.execute( + Addr::unchecked("sender"), + CosmosMsg::Wasm(WasmMsg::Migrate { + contract_addr: cw20_addr.to_string(), + new_code_id: cw20_id, + msg: to_binary(&MigrateMsg {}).unwrap(), + }), + ) + .unwrap(); + + // Smoke check that the contract still works. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr, + &QueryMsg::Balance { + address: "sender".to_string(), + }, + ) + .unwrap(); + + assert_eq!(balance.balance, Uint128::new(100)) + } + } + mod marketing { use super::*; diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index 8c45fc2fa..0cb18227a 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -111,3 +111,6 @@ pub enum QueryMsg { /// Return type: DownloadLogoResponse. DownloadLogo {}, } + +#[derive(Serialize, Deserialize, JsonSchema)] +pub struct MigrateMsg {} From 0d4eae49966cad7c4bfd0c0b5cdec840f623f1ea Mon Sep 17 00:00:00 2001 From: Zeke Medley Date: Wed, 6 Jul 2022 01:15:14 -0700 Subject: [PATCH 356/631] Add ability to unset minter in UpdateMinter message. --- contracts/cw20-base/src/contract.rs | 66 ++++++++++++++++++++++++----- packages/cw20/README.md | 5 +++ packages/cw20/src/msg.rs | 6 ++- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 2bdf482cb..09904fe15 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -393,7 +393,7 @@ pub fn execute_update_minter( deps: DepsMut, _env: Env, info: MessageInfo, - new_minter: String, + new_minter: Option, ) -> Result { let mut config = TOKEN_INFO .may_load(deps.storage)? @@ -404,18 +404,27 @@ pub fn execute_update_minter( return Err(ContractError::Unauthorized {}); } - let minter = deps.api.addr_validate(&new_minter)?; - let minter_data = MinterData { - minter, - cap: mint.cap, - }; - config.mint = Some(minter_data); + let minter_data = new_minter + .map(|new_minter| deps.api.addr_validate(&new_minter)) + .transpose()? + .map(|minter| MinterData { + minter, + cap: mint.cap, + }); + + config.mint = minter_data; TOKEN_INFO.save(deps.storage, &config)?; Ok(Response::default() .add_attribute("action", "update_minter") - .add_attribute("new_minter", new_minter)) + .add_attribute( + "new_minter", + config + .mint + .map(|m| m.minter.into_string()) + .unwrap_or_else(|| "None".to_string()), + )) } pub fn execute_update_marketing( @@ -927,7 +936,7 @@ mod tests { let new_minter = "new_minter"; let msg = ExecuteMsg::UpdateMinter { - new_minter: new_minter.to_string(), + new_minter: Some(new_minter.to_string()), }; let info = mock_info(&minter, &[]); @@ -956,7 +965,7 @@ mod tests { ); let msg = ExecuteMsg::UpdateMinter { - new_minter: String::from("new_minter"), + new_minter: Some("new_minter".to_string()), }; let info = mock_info("not the minter", &[]); @@ -965,6 +974,43 @@ mod tests { assert_eq!(err, ContractError::Unauthorized {}); } + #[test] + fn unset_minter() { + let mut deps = mock_dependencies(); + let minter = String::from("minter"); + let cap = None; + do_instantiate_with_minter( + deps.as_mut(), + &String::from("genesis"), + Uint128::new(1234), + &minter, + cap, + ); + + let msg = ExecuteMsg::UpdateMinter { new_minter: None }; + + let info = mock_info(&minter, &[]); + let env = mock_env(); + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert!(res.is_ok()); + let query_minter_msg = QueryMsg::Minter {}; + let res = query(deps.as_ref(), env, query_minter_msg); + let mint: Option = from_binary(&res.unwrap()).unwrap(); + + // Check that mint information was removed. + assert_eq!(mint, None); + + // Check that old minter can no longer mint. + let msg = ExecuteMsg::Mint { + recipient: String::from("lucky"), + amount: Uint128::new(222), + }; + let info = mock_info("minter", &[]); + let env = mock_env(); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); + } + #[test] fn no_one_mints_if_minter_unset() { let mut deps = mock_dependencies(); diff --git a/packages/cw20/README.md b/packages/cw20/README.md index 35be5f736..f4705625b 100644 --- a/packages/cw20/README.md +++ b/packages/cw20/README.md @@ -128,6 +128,11 @@ minter address and handle updating the ACL there. this will create `amount` new tokens (updating total supply) and add them to the balance of `recipient`, as long as it does not exceed the cap. +`UpdateMinter { new_minter: Option }` - Callable only by the +current minter. If `new_minter` is `Some(address)` the minter is set +to the specified address, otherwise the minter is removed and no +future minters may be set. + ### Queries `Minter{}` - Returns who and how much can be minted. Return type is diff --git a/packages/cw20/src/msg.rs b/packages/cw20/src/msg.rs index 4cd6fba63..f2f9708c9 100644 --- a/packages/cw20/src/msg.rs +++ b/packages/cw20/src/msg.rs @@ -55,8 +55,10 @@ pub enum Cw20ExecuteMsg { /// Only with the "mintable" extension. If authorized, creates amount new tokens /// and adds to the recipient balance. Mint { recipient: String, amount: Uint128 }, - /// Only with the "mintable" extension. The current minter may set a new minter. - UpdateMinter { new_minter: String }, + /// Only with the "mintable" extension. The current minter may set + /// a new minter. Setting the minter to None will remove the + /// token's minter forever. + UpdateMinter { new_minter: Option }, /// Only with the "marketing" extension. If authorized, updates marketing metadata. /// Setting None/null for any of these will leave it unchanged. /// Setting Some("") will clear this field on the contract storage From 10ec43fa4d0f27fc6520b7c1ef47a804374ec6f3 Mon Sep 17 00:00:00 2001 From: Zeke Medley Date: Wed, 6 Jul 2022 01:23:02 -0700 Subject: [PATCH 357/631] Use into_iter() instead of iter().cloned(). --- packages/controllers/src/claim.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index 60025fce3..01083fecb 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -65,7 +65,7 @@ impl<'a> Claims<'a> { let mut to_send = Uint128::zero(); self.0.update(storage, addr, |claim| -> StdResult<_> { let (_send, waiting): (Vec<_>, _) = - claim.unwrap_or_default().iter().cloned().partition(|c| { + claim.unwrap_or_default().into_iter().partition(|c| { // if mature and we can pay fully, then include in _send if c.release_at.is_expired(block) { if let Some(limit) = cap { From 0f98cab091b91029f3417ddf930c7710cf2c282b Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Wed, 13 Jul 2022 09:36:17 -0700 Subject: [PATCH 358/631] broken links: sandynet and NFTs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bcb3e607e..31569da36 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ many custom contracts. If you don't know what CosmWasm is, please check out [our homepage](https://cosmwasm.com) and [our documentation](https://docs.cosmwasm.com) to get more background. -We are running a [public testnet](https://github.com/CosmWasm/testnets/blob/master/sandynet-1/README.md) +We are running [public testnets](https://github.com/CosmWasm/testnets#running) you can use to test out any contracts. **Warning** None of these contracts have been audited and no liability is @@ -62,7 +62,7 @@ cleaner (before: `expires: {at_height: {height: 12345}}` after The most reusable components are the various cwXYZ specifications under `packages`. Each one defines a standard interface for different domains, e.g. [cw20](./packages/cw20/README.md) for fungible tokens, -[cw721](./packages/cw721/README.md) for non-fungible tokens, +[cw721](https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/README.md) for non-fungible tokens, [cw1](./packages/cw1/README.md) for "proxy contracts", etc. The interface comes with a human description in the READMEs, as well as Rust types that can be imported. From 13e0f9b6afa86b4c78547aecd2eecf61054d4db5 Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Wed, 13 Jul 2022 09:49:05 -0700 Subject: [PATCH 359/631] tiny grammar and typo in "Zeppelin" --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31569da36..c32b553ca 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ and depth of discussion can give an idea how much review was present. After that, fuzzing it (ideally with an intelligent fuzzer that understands the domain) can be valuable. And beyond that formal verification can provide even more assurance -(but is very time consuming and expensive). +(but is very time-consuming and expensive). ### Code Coverage @@ -213,7 +213,7 @@ relevant `Cargo.toml` file for clarity. All *specifications* will always be Apache-2.0. All contracts that are meant to be *building blocks* will also be Apache-2.0. This is along -the lines of Open Zepellin or other public references. +the lines of Open Zeppelin or other public references. Contracts that are "ready to deploy" may be licensed under AGPL 3.0 to encourage anyone using them to contribute back any improvements they From 297d1208131441cbec052bbe9e2832ac48be5677 Mon Sep 17 00:00:00 2001 From: Zeke Medley Date: Thu, 14 Jul 2022 13:59:10 -0700 Subject: [PATCH 360/631] Add entry to CHANGELOG.md. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecdbf257a..5135a2c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.4...HEAD) +**Merged pull requests:** + +- Add ability to unset minter in UpdateMinter message. [\#748](https://github.com/CosmWasm/cw-plus/pull/748) ([ezekiiel](https://github.com/ezekiiel)) + ## [v0.13.4](https://github.com/CosmWasm/cw-plus/tree/v0.13.4) (2022-06-02) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.3...v0.13.4) From fc8d166c4d8234138ff0b1b5957ffddbcfcc151c Mon Sep 17 00:00:00 2001 From: Pakorn Nathong Date: Tue, 14 Jun 2022 11:31:12 +0700 Subject: [PATCH 361/631] Add storage macro package --- Cargo.lock | 34 +- packages/storage-macro/Cargo.toml | 25 + packages/storage-macro/NOTICE | 14 + packages/storage-macro/README.md | 637 +++++++++++++++++++++ packages/storage-macro/src/lib.rs | 37 ++ packages/storage-macro/tests/index_list.rs | 60 ++ 6 files changed, 795 insertions(+), 12 deletions(-) create mode 100644 packages/storage-macro/Cargo.toml create mode 100644 packages/storage-macro/NOTICE create mode 100644 packages/storage-macro/README.md create mode 100644 packages/storage-macro/src/lib.rs create mode 100644 packages/storage-macro/tests/index_list.rs diff --git a/Cargo.lock b/Cargo.lock index b7cb3c849..390bf2ab1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,6 +406,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-storage-macro" +version = "0.13.4" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "serde", + "syn", +] + [[package]] name = "cw-storage-plus" version = "0.13.4" @@ -1022,11 +1032,11 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1343,13 +1353,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.94" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1410,16 +1420,16 @@ dependencies = [ ] [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-ident" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] -name = "unicode-xid" -version = "0.2.3" +name = "unicode-width" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "version_check" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml new file mode 100644 index 000000000..75cd97aa5 --- /dev/null +++ b/packages/storage-macro/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "cw-storage-macro" +version = "0.13.4" +authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] +edition = "2018" +description = "Macro helper for storage package" +license = "Apache-2.0" +repository = "https://github.com/CosmWasm/cw-plus" +homepage = "https://cosmwasm.com" +documentation = "https://docs.cosmwasm.com" + +[features] +default = ["iterator"] +iterator = ["cosmwasm-std/iterator"] + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0.96", features = ["full"] } + +[dev-dependencies] +cw-storage-plus = { version = "0.13.4", path = "../storage-plus" } +cosmwasm-std = { version = "1.0.0", default-features = false } +serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-macro/NOTICE b/packages/storage-macro/NOTICE new file mode 100644 index 000000000..838a67f47 --- /dev/null +++ b/packages/storage-macro/NOTICE @@ -0,0 +1,14 @@ +CW-Storage-Plus: Enhanced/experimental storage engines for CosmWasm +Copyright (C) 2020 Confio OÜ + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/storage-macro/README.md b/packages/storage-macro/README.md new file mode 100644 index 000000000..3e2691df1 --- /dev/null +++ b/packages/storage-macro/README.md @@ -0,0 +1,637 @@ +# CW-Storage-Plus: Enhanced storage engines for CosmWasm + +After building `cosmwasm-storage`, we realized many of the design decisions were +limiting us and producing a lot of needless boilerplate. The decision was made to leave +those APIs stable for anyone wanting a very basic abstraction on the KV-store and to +build a much more powerful and complex ORM layer that can provide powerful accessors +using complex key types, which are transparently turned into bytes. + +This led to a number of breaking API changes in this package of the course of several +releases as we updated this with lots of experience, user feedback, and deep dives to harness +the full power of generics. + +**Status: beta** + +As of `cw-storage-plus` `v0.12` the API should be quite stable. +There are no major API breaking issues pending, and all API changes will be documented +in [`MIGRATING.md`](../../MIGRATING.md). + +This has been heavily used in many production-quality contracts. +The code has demonstrated itself to be stable and powerful. +It has not been audited, and Confio assumes no liability, but we consider it mature enough +to be the **standard storage layer** for your contracts. + +## Usage Overview + +We introduce two main classes to provide a productive abstraction +on top of `cosmwasm_std::Storage`. They are `Item`, which is +a typed wrapper around one database key, providing some helper functions +for interacting with it without dealing with raw bytes. And `Map`, +which allows you to store multiple unique typed objects under a prefix, +indexed by a simple (`&[u8]`) or compound (eg. `(&[u8], &[u8])`) primary key. + +These correspond to the concepts represented in `cosmwasm_storage` by +`Singleton` and `Bucket`, but with a re-designed API and implementation +to require less typing for developers and less gas usage in the contracts. + +## Item + +The usage of an [`Item`](./src/item.rs) is pretty straight-forward. +You must simply provide the proper type, as well as a database key not +used by any other item. Then it will provide you with a nice interface +to interact with such data. + +If you are coming from using `Singleton`, the biggest change is that +we no longer store `Storage` inside, meaning we don't need read and write +variants of the object, just one type. Furthermore, we use `const fn` +to create the `Item`, allowing it to be defined as a global compile-time +constant rather than a function that must be constructed each time, +which saves gas as well as typing. + +Example Usage: + +```rust +#[derive(Serialize, Deserialize, PartialEq, Debug)] +struct Config { + pub owner: String, + pub max_tokens: i32, +} + +// note const constructor rather than 2 functions with Singleton +const CONFIG: Item = Item::new("config"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + + // may_load returns Option, so None if data is missing + // load returns T and Err(StdError::NotFound{}) if data is missing + let empty = CONFIG.may_load(&store)?; + assert_eq!(None, empty); + let cfg = Config { + owner: "admin".to_string(), + max_tokens: 1234, + }; + CONFIG.save(&mut store, &cfg)?; + let loaded = CONFIG.load(&store)?; + assert_eq!(cfg, loaded); + + // update an item with a closure (includes read and write) + // returns the newly saved value + let output = CONFIG.update(&mut store, |mut c| -> StdResult<_> { + c.max_tokens *= 2; + Ok(c) + })?; + assert_eq!(2468, output.max_tokens); + + // you can error in an update and nothing is saved + let failed = CONFIG.update(&mut store, |_| -> StdResult<_> { + Err(StdError::generic_err("failure mode")) + }); + assert!(failed.is_err()); + + // loading data will show the first update was saved + let loaded = CONFIG.load(&store)?; + let expected = Config { + owner: "admin".to_string(), + max_tokens: 2468, + }; + assert_eq!(expected, loaded); + + // we can remove data as well + CONFIG.remove(&mut store); + let empty = CONFIG.may_load(&store)?; + assert_eq!(None, empty); + + Ok(()) +} +``` + +## Map + +The usage of a [`Map`](./src/map.rs) is a little more complex, but +is still pretty straight-forward. You can imagine it as a storage-backed +`BTreeMap`, allowing key-value lookups with typed values. In addition, +we support not only simple binary keys (`&[u8]`), but tuples, which are +combined. This allows us to store allowances as composite keys +eg. `(owner, spender)` to look up the balance. + +Beyond direct lookups, we have a super-power not found in Ethereum - +iteration. That's right, you can list all items in a `Map`, or only +part of them. We can efficiently allow pagination over these items as +well, starting at the point the last query ended, with low gas costs. +This requires the `iterator` feature to be enabled in `cw-storage-plus` +(which automatically enables it in `cosmwasm-std` as well, and which is +enabled by default). + +If you are coming from using `Bucket`, the biggest change is that +we no longer store `Storage` inside, meaning we don't need read and write +variants of the object, just one type. Furthermore, we use `const fn` +to create the `Bucket`, allowing it to be defined as a global compile-time +constant rather than a function that must be constructed each time, +which saves gas as well as typing. In addition, the composite indexes +(tuples) are more ergonomic and expressive of intention, and the range +interface has been improved. + +Here is an example with normal (simple) keys: + +```rust +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +struct Data { + pub name: String, + pub age: i32, +} + +const PEOPLE: Map<&str, Data> = Map::new("people"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + let data = Data { + name: "John".to_string(), + age: 32, + }; + + // load and save with extra key argument + let empty = PEOPLE.may_load(&store, "john")?; + assert_eq!(None, empty); + PEOPLE.save(&mut store, "john", &data)?; + let loaded = PEOPLE.load(&store, "john")?; + assert_eq!(data, loaded); + + // nothing on another key + let missing = PEOPLE.may_load(&store, "jack")?; + assert_eq!(None, missing); + + // update function for new or existing keys + let birthday = |d: Option| -> StdResult { + match d { + Some(one) => Ok(Data { + name: one.name, + age: one.age + 1, + }), + None => Ok(Data { + name: "Newborn".to_string(), + age: 0, + }), + } + }; + + let old_john = PEOPLE.update(&mut store, "john", birthday)?; + assert_eq!(33, old_john.age); + assert_eq!("John", old_john.name.as_str()); + + let new_jack = PEOPLE.update(&mut store, "jack", birthday)?; + assert_eq!(0, new_jack.age); + assert_eq!("Newborn", new_jack.name.as_str()); + + // update also changes the store + assert_eq!(old_john, PEOPLE.load(&store, "john")?); + assert_eq!(new_jack, PEOPLE.load(&store, "jack")?); + + // removing leaves us empty + PEOPLE.remove(&mut store, "john"); + let empty = PEOPLE.may_load(&store, "john")?; + assert_eq!(None, empty); + + Ok(()) +} +``` + +### Key types + +A `Map` key can be anything that implements the `PrimaryKey` trait. There are a series of implementations of +`PrimaryKey` already provided (see [keys.rs](./src/keys.rs)): + + - `impl<'a> PrimaryKey<'a> for &'a [u8]` + - `impl<'a> PrimaryKey<'a> for &'a str` + - `impl<'a> PrimaryKey<'a> for Vec` + - `impl<'a> PrimaryKey<'a> for String` + - `impl<'a> PrimaryKey<'a> for Addr` + - `impl<'a> PrimaryKey<'a> for &'a Addr` + - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a>> PrimaryKey<'a> for (T, U)` + - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a> + Prefixer<'a>, V: PrimaryKey<'a>> PrimaryKey<'a> for (T, U, V)` + - `PrimaryKey` implemented for unsigned integers up to `u64` + - `PrimaryKey` implemented for signed integers up to `i64` + +That means that byte and string slices, byte vectors, and strings, can be conveniently used as keys. +Moreover, some other types can be used as well, like addresses and address references, pairs, triples, and +integer types. + +If the key represents an address, we suggest using `&Addr` for keys in storage, instead of `String` or string slices. +This implies doing address validation through `addr_validate` on any address passed in via a message, to ensure it's a +legitimate address, and not random text which will fail later. +`pub fn addr_validate(&self, &str) -> Addr` in `deps.api` can be used for address validation, and the returned `Addr` +can then be conveniently used as key in a `Map` or similar structure. + +It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`), +as that will typically save some cloning during key reading / writing. + +### Composite Keys + +There are times when we want to use multiple items as a key. For example, when +storing allowances based on account owner and spender. We could try to manually +concatenate them before calling, but that can lead to overlap, and is a bit +low-level for us. Also, by explicitly separating the keys, we can easily provide +helpers to do range queries over a prefix, such as "show me all allowances for +one owner" (first part of the composite key). Just like you'd expect from your +favorite database. + +Here's how we use it with composite keys. Just define a tuple as a key and use that +everywhere you used a byte slice above. + +```rust +// Note the tuple for primary key. We support one slice, or a 2 or 3-tuple. +// Adding longer tuples is possible, but unlikely to be needed. +const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + + // save and load on a composite key + let empty = ALLOWANCE.may_load(&store, ("owner", "spender"))?; + assert_eq!(None, empty); + ALLOWANCE.save(&mut store, ("owner", "spender"), &777)?; + let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; + assert_eq!(777, loaded); + + // doesn't appear under other key (even if a concat would be the same) + let different = ALLOWANCE.may_load(&store, ("owners", "pender")).unwrap(); + assert_eq!(None, different); + + // simple update + ALLOWANCE.update(&mut store, ("owner", "spender"), |v| { + Ok(v.unwrap_or_default() + 222) + })?; + let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; + assert_eq!(999, loaded); + + Ok(()) +} +``` + +### Path + +Under the scenes, we create a `Path` from the `Map` when accessing a key. +`PEOPLE.load(&store, b"jack") == PEOPLE.key(b"jack").load()`. +`Map.key()` returns a `Path`, which has the same interface as `Item`, +re-using the calculated path to this key. + +For simple keys, this is just a bit less typing and a bit less gas if you +use the same key for many calls. However, for composite keys, like +`(b"owner", b"spender")` it is **much** less typing. And highly recommended anywhere +you will use a composite key even twice: + +```rust +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +struct Data { + pub name: String, + pub age: i32, +} + +const PEOPLE: Map<&str, Data> = Map::new("people"); +const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + let data = Data { + name: "John".to_string(), + age: 32, + }; + + // create a Path one time to use below + let john = PEOPLE.key("john"); + + // Use this just like an Item above + let empty = john.may_load(&store)?; + assert_eq!(None, empty); + john.save(&mut store, &data)?; + let loaded = john.load(&store)?; + assert_eq!(data, loaded); + john.remove(&mut store); + let empty = john.may_load(&store)?; + assert_eq!(None, empty); + + // Same for composite keys, just use both parts in `key()`. + // Notice how much less verbose than the above example. + let allow = ALLOWANCE.key(("owner", "spender")); + allow.save(&mut store, &1234)?; + let loaded = allow.load(&store)?; + assert_eq!(1234, loaded); + allow.update(&mut store, |x| Ok(x.unwrap_or_default() * 2))?; + let loaded = allow.load(&store)?; + assert_eq!(2468, loaded); + + Ok(()) +} +``` + +### Prefix + +In addition to getting one particular item out of a map, we can iterate over the map +(or a subset of the map). This let us answer questions like "show me all tokens", +and we provide some nice [`Bound`](#bound) helpers to easily allow pagination or custom ranges. + +The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly +one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. +If `map.key()` took `&[u8]`, `map.prefix()` takes `()`). Once we have a prefix space, we can iterate +over all items with `range(store, min, max, order)`. It supports `Order::Ascending` or `Order::Descending`. +`min` is the lower bound and `max` is the higher bound. + +If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to +limit the results to `n` items and start doing pagination. You can also set the `min` bound to +eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with +`take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any +perfect matches. + +### Bound + +`Bound` is a helper to build type-safe bounds on the keys or sub-keys you want to iterate over. +It also supports a raw (`Vec`) bounds specification, for the cases you don't want or can't use typed bounds. + +```rust +#[derive(Clone, Debug)] +pub enum Bound<'a, K: PrimaryKey<'a>> { + Inclusive((K, PhantomData<&'a bool>)), + Exclusive((K, PhantomData<&'a bool>)), + InclusiveRaw(Vec), + ExclusiveRaw(Vec), +} +``` + +To better understand the API, please check the following example: +```rust +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +struct Data { + pub name: String, + pub age: i32, +} + +const PEOPLE: Map<&str, Data> = Map::new("people"); +const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + + // save and load on two keys + let data = Data { name: "John".to_string(), age: 32 }; + PEOPLE.save(&mut store, "john", &data)?; + let data2 = Data { name: "Jim".to_string(), age: 44 }; + PEOPLE.save(&mut store, "jim", &data2)?; + + // iterate over them all + let all: StdResult> = PEOPLE + .range(&store, None, None, Order::Ascending) + .collect(); + assert_eq!( + all?, + vec![("jim".to_vec(), data2), ("john".to_vec(), data.clone())] + ); + + // or just show what is after jim + let all: StdResult> = PEOPLE + .range( + &store, + Some(Bound::exclusive("jim")), + None, + Order::Ascending, + ) + .collect(); + assert_eq!(all?, vec![("john".to_vec(), data)]); + + // save and load on three keys, one under different owner + ALLOWANCE.save(&mut store, ("owner", "spender"), &1000)?; + ALLOWANCE.save(&mut store, ("owner", "spender2"), &3000)?; + ALLOWANCE.save(&mut store, ("owner2", "spender"), &5000)?; + + // get all under one key + let all: StdResult> = ALLOWANCE + .prefix("owner") + .range(&store, None, None, Order::Ascending) + .collect(); + assert_eq!( + all?, + vec![("spender".to_vec(), 1000), ("spender2".to_vec(), 3000)] + ); + + // Or ranges between two items (even reverse) + let all: StdResult> = ALLOWANCE + .prefix("owner") + .range( + &store, + Some(Bound::exclusive("spender1")), + Some(Bound::inclusive("spender2")), + Order::Descending, + ) + .collect(); + assert_eq!(all?, vec![("spender2".to_vec(), 3000)]); + + Ok(()) +} +``` + +**NB**: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), +below. + +## IndexedMap + +Let's see one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. + +### Definition + +```rust +pub struct TokenIndexes<'a> { + pub owner: MultiIndex<'a, Addr, TokenInfo, String>, +} + +impl<'a> IndexList for TokenIndexes<'a> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.owner]; + Box::new(v.into_iter()) + } +} + +pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { + let indexes = TokenIndexes { + owner: MultiIndex::new( + |d: &TokenInfo| d.owner.clone(), + "tokens", + "tokens__owner", + ), + }; + IndexedMap::new("tokens", indexes) +} +``` + +Let's discuss this piece by piece: +```rust +pub struct TokenIndexes<'a> { + pub owner: MultiIndex<'a, Addr, TokenInfo, String>, +} +``` + +These are the index definitions. Here there's only one index, called `owner`. There could be more, as public +members of the `TokenIndexes` struct. +We see that the `owner` index is a `MultiIndex`. A multi-index can have repeated values as keys. The primary key is +used internally as the last element of the multi-index key, to disambiguate repeated index values. +Like the name implies, this is an index over tokens, by owner. Given that an owner can have multiple tokens, +we need a `MultiIndex` to be able to list / iterate over all the tokens he has. + +The `TokenInfo` data will originally be stored by `token_id` (which is a string value). +You can see this in the token creation code: +```rust + tokens().update(deps.storage, &msg.token_id, |old| match old { + Some(_) => Err(ContractError::Claimed {}), + None => Ok(token), + })?; +``` +(Incidentally, this is using `update` instead of `save`, to avoid overwriting an already existing token). + +Given that `token_id` is a string value, we specify `String` as the last argument of the `MultiIndex` definition. +That way, the deserialization of the primary key will be done to the right type (an owned string). + +**NB**: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of +this last type parameter is crucial, for properly using type-safe bounds. +See [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), below. + +Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr`). So that we can list all the tokens +an owner has. That's why the `owner` index key is `Addr`. + +Other important thing here is that the key (and its components, in the case of a composite key) must implement +the `PrimaryKey` trait. You can see that `Addr` does implement `PrimaryKey`: + +```rust +impl<'a> PrimaryKey<'a> for Addr { + type Prefix = (); + type SubPrefix = (); + type Suffix = Self; + type SuperSuffix = Self; + + fn key(&self) -> Vec { + // this is simple, we don't add more prefixes + vec![Key::Ref(self.as_bytes())] + } +} +``` + +--- + +We can now see how it all works, taking a look at the remaining code: + +```rust +impl<'a> IndexList for TokenIndexes<'a> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.owner]; + Box::new(v.into_iter()) + } +} +``` + +This implements the `IndexList` trait for `TokenIndexes`. + +**NB**: this code is more or less boiler-plate, and needed for the internals. Do not try to customize this; +just return a list of all indexes. +Implementing this trait serves two purposes (which are really one and the same): it allows the indexes +to be queried through `get_indexes`, and, it allows `TokenIndexes` to be treated as an `IndexList`. So that +it can be passed as a parameter during `IndexedMap` construction, below: + +```rust +pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { + let indexes = TokenIndexes { + owner: MultiIndex::new( + |d: &TokenInfo| d.owner.clone(), + "tokens", + "tokens__owner", + ), + }; + IndexedMap::new("tokens", indexes) +} +``` + +Here `tokens()` is just a helper function, that simplifies the `IndexedMap` construction for us. First the +index (es) is (are) created, and then, the `IndexedMap` is created and returned. + +During index creation, we must supply an index function per index +```rust + owner: MultiIndex::new(|d: &TokenInfo| d.owner.clone(), +``` +which is the one that will take the value of the original map and create the index key from it. +Of course, this requires that the elements required for the index key are present in the value. +Besides the index function, we must also supply the namespace of the pk, and the one for the new index. + +--- + +After that, we just create and return the `IndexedMap`: + +```rust + IndexedMap::new("tokens", indexes) +``` + +Here of course, the namespace of the pk must match the one used during index(es) creation. And, we pass our +`TokenIndexes` (as an `IndexList`-type parameter) as second argument. Connecting in this way the underlying `Map` +for the pk, with the defined indexes. + +So, `IndexedMap` (and the other `Indexed*` types) is just a wrapper / extension around `Map`, that provides +a number of index functions and namespaces to create indexes over the original `Map` data. It also implements +calling these index functions during value storage / update / removal, so that you can forget about it, +and just use the indexed data. + +### Usage + +An example of use, where `owner` is a `String` value passed as a parameter, and `start_after` and `limit` optionally +define the pagination range: + +Notice this uses `prefix()`, explained above in the `Map` section. + +```rust + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.map(Bound::exclusive); + let owner_addr = deps.api.addr_validate(&owner)?; + + let res: Result, _> = tokens() + .idx + .owner + .prefix(owner_addr) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect(); + let tokens = res?; +``` +Now `tokens` contains `(token_id, TokenInfo)` pairs for the given `owner`. +The pk values are `Vec` in the case of `range_raw()`, but will be deserialized to the proper type using +`range()`; provided that the pk deserialization type (`String`, in this case) is correctly specified +in the `MultiIndex` definition (see [Index keys deserialization](#index-keys-deserialization), +below). + +Another example that is similar, but returning only the (raw) `token_id`s, using the `keys_raw()` method: +```rust + let pks: Vec<_> = tokens() + .idx + .owner + .prefix(owner_addr) + .keys_raw( + deps.storage, + start, + None, + Order::Ascending, + ) + .take(limit) + .collect(); +``` +Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `keys` instead, +a deserialized key can be obtained, as detailed in the next section. + +### Index keys deserialization + +For `UniqueIndex` and `MultiIndex`, the primary key (`PK`) type needs to be specified, in order to deserialize +the primary key to it. +This `PK` type specification is also important for `MultiIndex` type-safe bounds, as the primary key +is part of the multi-index key. See next section, [Type-safe bounds over MultiIndex](#type-safe-bounds-over-multiindex). + +**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will (if possible) +be automated in the future (https://github.com/CosmWasm/cw-plus/issues/531). + +### Type-safe bounds over MultiIndex + +In the particular case of `MultiIndex`, the primary key (`PK`) type parameter also defines the type of the (partial) bounds over +the index key (the part that corresponds to the primary key, that is). +So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type +to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. diff --git a/packages/storage-macro/src/lib.rs b/packages/storage-macro/src/lib.rs new file mode 100644 index 000000000..366723ca5 --- /dev/null +++ b/packages/storage-macro/src/lib.rs @@ -0,0 +1,37 @@ +use proc_macro::TokenStream; +use syn::{ + Ident, + __private::{quote::quote, Span}, + parse_macro_input, ItemStruct, +}; + +#[proc_macro_attribute] +pub fn index_list(attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as ItemStruct); + + let ty = Ident::new(&attr.to_string(), Span::call_site()); + let struct_ty = input.ident.clone(); + + let names = input + .fields + .clone() + .into_iter() + .map(|e| { + let name = e.ident.unwrap(); + quote! { &self.#name } + }) + .collect::>(); + + let expanded = quote! { + #input + + impl cw_storage_plus::IndexList<#ty> for #struct_ty<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn cw_storage_plus::Index<#ty>> = vec![#(#names),*]; + Box::new(v.into_iter()) + } + } + }; + + TokenStream::from(expanded) +} diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs new file mode 100644 index 000000000..3a192691b --- /dev/null +++ b/packages/storage-macro/tests/index_list.rs @@ -0,0 +1,60 @@ +use cosmwasm_std::{testing::MockStorage, Addr}; +use cw_storage_macro::index_list; +use cw_storage_plus::{IndexedMap, MultiIndex, UniqueIndex}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +struct TestStruct { + id: u64, + id2: u32, + addr: Addr, +} + +#[index_list(TestStruct)] +struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, +} + +#[test] +fn compile() { + let _: IndexedMap = IndexedMap::new( + "t", + TestIndexes { + id: MultiIndex::new(|t| t.id2, "t", "t_2"), + addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), + }, + ); +} + +#[test] +fn works() { + let mut storage = MockStorage::new(); + let idm: IndexedMap = IndexedMap::new( + "t", + TestIndexes { + id: MultiIndex::new(|t| t.id2, "t", "t_2"), + addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), + }, + ); + + idm.save( + &mut storage, + 0, + &TestStruct { + id: 0, + id2: 100, + addr: Addr::unchecked("1"), + }, + ) + .unwrap(); + + assert_eq!( + idm.load(&storage, 0).unwrap(), + TestStruct { + id: 0, + id2: 100, + addr: Addr::unchecked("1"), + } + ); +} From fbc308280a6ac4498c2fd3b2630adf8d273afcf1 Mon Sep 17 00:00:00 2001 From: Pakorn Nathong Date: Tue, 14 Jun 2022 11:39:49 +0700 Subject: [PATCH 362/631] Add reexport macro to cw-storage-plus package --- Cargo.lock | 1 + packages/storage-plus/Cargo.toml | 2 ++ packages/storage-plus/src/lib.rs | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 390bf2ab1..2d69171e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -422,6 +422,7 @@ version = "0.13.4" dependencies = [ "cosmwasm-std", "criterion", + "cw-storage-macro", "rand", "schemars", "serde", diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 5370e5eb2..524890ef1 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -11,6 +11,7 @@ homepage = "https://cosmwasm.com" [features] default = ["iterator"] iterator = ["cosmwasm-std/iterator"] +macro = ["cw-storage-macro"] [lib] # See https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options @@ -20,6 +21,7 @@ bench = false cosmwasm-std = { version = "1.0.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cw-storage-macro = { version = "0.13.4", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = [ "html_reports" ] } diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 5562073c0..d6f93efb3 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -40,3 +40,10 @@ pub use path::Path; pub use prefix::{range_with_prefix, Prefix}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; + +#[cfg(all(feature = "iterator", feature = "macro"))] +#[macro_use] +extern crate cw_storage_macro; +#[cfg(all(feature = "iterator", feature = "macro"))] +#[doc(hidden)] +pub use cw_storage_macro::*; From 6743898aa05ab4b6e6337ffdcc5818bd40018b8d Mon Sep 17 00:00:00 2001 From: Pakorn Nathong Date: Tue, 14 Jun 2022 11:52:57 +0700 Subject: [PATCH 363/631] Update notice and readme --- packages/storage-macro/NOTICE | 2 +- packages/storage-macro/README.md | 641 +------------------------------ 2 files changed, 14 insertions(+), 629 deletions(-) diff --git a/packages/storage-macro/NOTICE b/packages/storage-macro/NOTICE index 838a67f47..a2d3c8655 100644 --- a/packages/storage-macro/NOTICE +++ b/packages/storage-macro/NOTICE @@ -1,4 +1,4 @@ -CW-Storage-Plus: Enhanced/experimental storage engines for CosmWasm +CW-Storage-Macro: Macro helper for storage package Copyright (C) 2020 Confio OÜ Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/storage-macro/README.md b/packages/storage-macro/README.md index 3e2691df1..200c2dfa4 100644 --- a/packages/storage-macro/README.md +++ b/packages/storage-macro/README.md @@ -1,637 +1,22 @@ -# CW-Storage-Plus: Enhanced storage engines for CosmWasm +# CW-Storage-Plus: Macro helper for storage package -After building `cosmwasm-storage`, we realized many of the design decisions were -limiting us and producing a lot of needless boilerplate. The decision was made to leave -those APIs stable for anyone wanting a very basic abstraction on the KV-store and to -build a much more powerful and complex ORM layer that can provide powerful accessors -using complex key types, which are transparently turned into bytes. +Procedural macros helper for interacting with cw-storage-plus and cosmwasm-storage. -This led to a number of breaking API changes in this package of the course of several -releases as we updated this with lots of experience, user feedback, and deep dives to harness -the full power of generics. +## Current features -**Status: beta** - -As of `cw-storage-plus` `v0.12` the API should be quite stable. -There are no major API breaking issues pending, and all API changes will be documented -in [`MIGRATING.md`](../../MIGRATING.md). - -This has been heavily used in many production-quality contracts. -The code has demonstrated itself to be stable and powerful. -It has not been audited, and Confio assumes no liability, but we consider it mature enough -to be the **standard storage layer** for your contracts. - -## Usage Overview - -We introduce two main classes to provide a productive abstraction -on top of `cosmwasm_std::Storage`. They are `Item`, which is -a typed wrapper around one database key, providing some helper functions -for interacting with it without dealing with raw bytes. And `Map`, -which allows you to store multiple unique typed objects under a prefix, -indexed by a simple (`&[u8]`) or compound (eg. `(&[u8], &[u8])`) primary key. - -These correspond to the concepts represented in `cosmwasm_storage` by -`Singleton` and `Bucket`, but with a re-designed API and implementation -to require less typing for developers and less gas usage in the contracts. - -## Item - -The usage of an [`Item`](./src/item.rs) is pretty straight-forward. -You must simply provide the proper type, as well as a database key not -used by any other item. Then it will provide you with a nice interface -to interact with such data. - -If you are coming from using `Singleton`, the biggest change is that -we no longer store `Storage` inside, meaning we don't need read and write -variants of the object, just one type. Furthermore, we use `const fn` -to create the `Item`, allowing it to be defined as a global compile-time -constant rather than a function that must be constructed each time, -which saves gas as well as typing. - -Example Usage: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug)] -struct Config { - pub owner: String, - pub max_tokens: i32, -} - -// note const constructor rather than 2 functions with Singleton -const CONFIG: Item = Item::new("config"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // may_load returns Option, so None if data is missing - // load returns T and Err(StdError::NotFound{}) if data is missing - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg)?; - let loaded = CONFIG.load(&store)?; - assert_eq!(cfg, loaded); - - // update an item with a closure (includes read and write) - // returns the newly saved value - let output = CONFIG.update(&mut store, |mut c| -> StdResult<_> { - c.max_tokens *= 2; - Ok(c) - })?; - assert_eq!(2468, output.max_tokens); - - // you can error in an update and nothing is saved - let failed = CONFIG.update(&mut store, |_| -> StdResult<_> { - Err(StdError::generic_err("failure mode")) - }); - assert!(failed.is_err()); - - // loading data will show the first update was saved - let loaded = CONFIG.load(&store)?; - let expected = Config { - owner: "admin".to_string(), - max_tokens: 2468, - }; - assert_eq!(expected, loaded); - - // we can remove data as well - CONFIG.remove(&mut store); - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - - Ok(()) -} -``` - -## Map - -The usage of a [`Map`](./src/map.rs) is a little more complex, but -is still pretty straight-forward. You can imagine it as a storage-backed -`BTreeMap`, allowing key-value lookups with typed values. In addition, -we support not only simple binary keys (`&[u8]`), but tuples, which are -combined. This allows us to store allowances as composite keys -eg. `(owner, spender)` to look up the balance. - -Beyond direct lookups, we have a super-power not found in Ethereum - -iteration. That's right, you can list all items in a `Map`, or only -part of them. We can efficiently allow pagination over these items as -well, starting at the point the last query ended, with low gas costs. -This requires the `iterator` feature to be enabled in `cw-storage-plus` -(which automatically enables it in `cosmwasm-std` as well, and which is -enabled by default). - -If you are coming from using `Bucket`, the biggest change is that -we no longer store `Storage` inside, meaning we don't need read and write -variants of the object, just one type. Furthermore, we use `const fn` -to create the `Bucket`, allowing it to be defined as a global compile-time -constant rather than a function that must be constructed each time, -which saves gas as well as typing. In addition, the composite indexes -(tuples) are more ergonomic and expressive of intention, and the range -interface has been improved. - -Here is an example with normal (simple) keys: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // load and save with extra key argument - let empty = PEOPLE.may_load(&store, "john")?; - assert_eq!(None, empty); - PEOPLE.save(&mut store, "john", &data)?; - let loaded = PEOPLE.load(&store, "john")?; - assert_eq!(data, loaded); - - // nothing on another key - let missing = PEOPLE.may_load(&store, "jack")?; - assert_eq!(None, missing); - - // update function for new or existing keys - let birthday = |d: Option| -> StdResult { - match d { - Some(one) => Ok(Data { - name: one.name, - age: one.age + 1, - }), - None => Ok(Data { - name: "Newborn".to_string(), - age: 0, - }), - } - }; - - let old_john = PEOPLE.update(&mut store, "john", birthday)?; - assert_eq!(33, old_john.age); - assert_eq!("John", old_john.name.as_str()); - - let new_jack = PEOPLE.update(&mut store, "jack", birthday)?; - assert_eq!(0, new_jack.age); - assert_eq!("Newborn", new_jack.name.as_str()); - - // update also changes the store - assert_eq!(old_john, PEOPLE.load(&store, "john")?); - assert_eq!(new_jack, PEOPLE.load(&store, "jack")?); - - // removing leaves us empty - PEOPLE.remove(&mut store, "john"); - let empty = PEOPLE.may_load(&store, "john")?; - assert_eq!(None, empty); - - Ok(()) -} -``` - -### Key types - -A `Map` key can be anything that implements the `PrimaryKey` trait. There are a series of implementations of -`PrimaryKey` already provided (see [keys.rs](./src/keys.rs)): - - - `impl<'a> PrimaryKey<'a> for &'a [u8]` - - `impl<'a> PrimaryKey<'a> for &'a str` - - `impl<'a> PrimaryKey<'a> for Vec` - - `impl<'a> PrimaryKey<'a> for String` - - `impl<'a> PrimaryKey<'a> for Addr` - - `impl<'a> PrimaryKey<'a> for &'a Addr` - - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a>> PrimaryKey<'a> for (T, U)` - - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a> + Prefixer<'a>, V: PrimaryKey<'a>> PrimaryKey<'a> for (T, U, V)` - - `PrimaryKey` implemented for unsigned integers up to `u64` - - `PrimaryKey` implemented for signed integers up to `i64` - -That means that byte and string slices, byte vectors, and strings, can be conveniently used as keys. -Moreover, some other types can be used as well, like addresses and address references, pairs, triples, and -integer types. - -If the key represents an address, we suggest using `&Addr` for keys in storage, instead of `String` or string slices. -This implies doing address validation through `addr_validate` on any address passed in via a message, to ensure it's a -legitimate address, and not random text which will fail later. -`pub fn addr_validate(&self, &str) -> Addr` in `deps.api` can be used for address validation, and the returned `Addr` -can then be conveniently used as key in a `Map` or similar structure. - -It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`), -as that will typically save some cloning during key reading / writing. - -### Composite Keys - -There are times when we want to use multiple items as a key. For example, when -storing allowances based on account owner and spender. We could try to manually -concatenate them before calling, but that can lead to overlap, and is a bit -low-level for us. Also, by explicitly separating the keys, we can easily provide -helpers to do range queries over a prefix, such as "show me all allowances for -one owner" (first part of the composite key). Just like you'd expect from your -favorite database. - -Here's how we use it with composite keys. Just define a tuple as a key and use that -everywhere you used a byte slice above. - -```rust -// Note the tuple for primary key. We support one slice, or a 2 or 3-tuple. -// Adding longer tuples is possible, but unlikely to be needed. -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // save and load on a composite key - let empty = ALLOWANCE.may_load(&store, ("owner", "spender"))?; - assert_eq!(None, empty); - ALLOWANCE.save(&mut store, ("owner", "spender"), &777)?; - let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; - assert_eq!(777, loaded); - - // doesn't appear under other key (even if a concat would be the same) - let different = ALLOWANCE.may_load(&store, ("owners", "pender")).unwrap(); - assert_eq!(None, different); - - // simple update - ALLOWANCE.update(&mut store, ("owner", "spender"), |v| { - Ok(v.unwrap_or_default() + 222) - })?; - let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; - assert_eq!(999, loaded); - - Ok(()) -} -``` - -### Path - -Under the scenes, we create a `Path` from the `Map` when accessing a key. -`PEOPLE.load(&store, b"jack") == PEOPLE.key(b"jack").load()`. -`Map.key()` returns a `Path`, which has the same interface as `Item`, -re-using the calculated path to this key. - -For simple keys, this is just a bit less typing and a bit less gas if you -use the same key for many calls. However, for composite keys, like -`(b"owner", b"spender")` it is **much** less typing. And highly recommended anywhere -you will use a composite key even twice: +Auto generate IndexList impl for your indexes struct. ```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // create a Path one time to use below - let john = PEOPLE.key("john"); - - // Use this just like an Item above - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - john.save(&mut store, &data)?; - let loaded = john.load(&store)?; - assert_eq!(data, loaded); - john.remove(&mut store); - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - - // Same for composite keys, just use both parts in `key()`. - // Notice how much less verbose than the above example. - let allow = ALLOWANCE.key(("owner", "spender")); - allow.save(&mut store, &1234)?; - let loaded = allow.load(&store)?; - assert_eq!(1234, loaded); - allow.update(&mut store, |x| Ok(x.unwrap_or_default() * 2))?; - let loaded = allow.load(&store)?; - assert_eq!(2468, loaded); - - Ok(()) +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +struct TestStruct { + id: u64, + id2: u32, + addr: Addr, } -``` - -### Prefix - -In addition to getting one particular item out of a map, we can iterate over the map -(or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice [`Bound`](#bound) helpers to easily allow pagination or custom ranges. - -The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly -one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. -If `map.key()` took `&[u8]`, `map.prefix()` takes `()`). Once we have a prefix space, we can iterate -over all items with `range(store, min, max, order)`. It supports `Order::Ascending` or `Order::Descending`. -`min` is the lower bound and `max` is the higher bound. - -If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to -limit the results to `n` items and start doing pagination. You can also set the `min` bound to -eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with -`take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any -perfect matches. -### Bound - -`Bound` is a helper to build type-safe bounds on the keys or sub-keys you want to iterate over. -It also supports a raw (`Vec`) bounds specification, for the cases you don't want or can't use typed bounds. - -```rust -#[derive(Clone, Debug)] -pub enum Bound<'a, K: PrimaryKey<'a>> { - Inclusive((K, PhantomData<&'a bool>)), - Exclusive((K, PhantomData<&'a bool>)), - InclusiveRaw(Vec), - ExclusiveRaw(Vec), +#[index_list(TestStruct)] // <- Add this line right here,. +struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, } ``` - -To better understand the API, please check the following example: -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // save and load on two keys - let data = Data { name: "John".to_string(), age: 32 }; - PEOPLE.save(&mut store, "john", &data)?; - let data2 = Data { name: "Jim".to_string(), age: 44 }; - PEOPLE.save(&mut store, "jim", &data2)?; - - // iterate over them all - let all: StdResult> = PEOPLE - .range(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![("jim".to_vec(), data2), ("john".to_vec(), data.clone())] - ); - - // or just show what is after jim - let all: StdResult> = PEOPLE - .range( - &store, - Some(Bound::exclusive("jim")), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(all?, vec![("john".to_vec(), data)]); - - // save and load on three keys, one under different owner - ALLOWANCE.save(&mut store, ("owner", "spender"), &1000)?; - ALLOWANCE.save(&mut store, ("owner", "spender2"), &3000)?; - ALLOWANCE.save(&mut store, ("owner2", "spender"), &5000)?; - - // get all under one key - let all: StdResult> = ALLOWANCE - .prefix("owner") - .range(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![("spender".to_vec(), 1000), ("spender2".to_vec(), 3000)] - ); - - // Or ranges between two items (even reverse) - let all: StdResult> = ALLOWANCE - .prefix("owner") - .range( - &store, - Some(Bound::exclusive("spender1")), - Some(Bound::inclusive("spender2")), - Order::Descending, - ) - .collect(); - assert_eq!(all?, vec![("spender2".to_vec(), 3000)]); - - Ok(()) -} -``` - -**NB**: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), -below. - -## IndexedMap - -Let's see one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. - -### Definition - -```rust -pub struct TokenIndexes<'a> { - pub owner: MultiIndex<'a, Addr, TokenInfo, String>, -} - -impl<'a> IndexList for TokenIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.owner]; - Box::new(v.into_iter()) - } -} - -pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { - let indexes = TokenIndexes { - owner: MultiIndex::new( - |d: &TokenInfo| d.owner.clone(), - "tokens", - "tokens__owner", - ), - }; - IndexedMap::new("tokens", indexes) -} -``` - -Let's discuss this piece by piece: -```rust -pub struct TokenIndexes<'a> { - pub owner: MultiIndex<'a, Addr, TokenInfo, String>, -} -``` - -These are the index definitions. Here there's only one index, called `owner`. There could be more, as public -members of the `TokenIndexes` struct. -We see that the `owner` index is a `MultiIndex`. A multi-index can have repeated values as keys. The primary key is -used internally as the last element of the multi-index key, to disambiguate repeated index values. -Like the name implies, this is an index over tokens, by owner. Given that an owner can have multiple tokens, -we need a `MultiIndex` to be able to list / iterate over all the tokens he has. - -The `TokenInfo` data will originally be stored by `token_id` (which is a string value). -You can see this in the token creation code: -```rust - tokens().update(deps.storage, &msg.token_id, |old| match old { - Some(_) => Err(ContractError::Claimed {}), - None => Ok(token), - })?; -``` -(Incidentally, this is using `update` instead of `save`, to avoid overwriting an already existing token). - -Given that `token_id` is a string value, we specify `String` as the last argument of the `MultiIndex` definition. -That way, the deserialization of the primary key will be done to the right type (an owned string). - -**NB**: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of -this last type parameter is crucial, for properly using type-safe bounds. -See [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), below. - -Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr`). So that we can list all the tokens -an owner has. That's why the `owner` index key is `Addr`. - -Other important thing here is that the key (and its components, in the case of a composite key) must implement -the `PrimaryKey` trait. You can see that `Addr` does implement `PrimaryKey`: - -```rust -impl<'a> PrimaryKey<'a> for Addr { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self.as_bytes())] - } -} -``` - ---- - -We can now see how it all works, taking a look at the remaining code: - -```rust -impl<'a> IndexList for TokenIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.owner]; - Box::new(v.into_iter()) - } -} -``` - -This implements the `IndexList` trait for `TokenIndexes`. - -**NB**: this code is more or less boiler-plate, and needed for the internals. Do not try to customize this; -just return a list of all indexes. -Implementing this trait serves two purposes (which are really one and the same): it allows the indexes -to be queried through `get_indexes`, and, it allows `TokenIndexes` to be treated as an `IndexList`. So that -it can be passed as a parameter during `IndexedMap` construction, below: - -```rust -pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { - let indexes = TokenIndexes { - owner: MultiIndex::new( - |d: &TokenInfo| d.owner.clone(), - "tokens", - "tokens__owner", - ), - }; - IndexedMap::new("tokens", indexes) -} -``` - -Here `tokens()` is just a helper function, that simplifies the `IndexedMap` construction for us. First the -index (es) is (are) created, and then, the `IndexedMap` is created and returned. - -During index creation, we must supply an index function per index -```rust - owner: MultiIndex::new(|d: &TokenInfo| d.owner.clone(), -``` -which is the one that will take the value of the original map and create the index key from it. -Of course, this requires that the elements required for the index key are present in the value. -Besides the index function, we must also supply the namespace of the pk, and the one for the new index. - ---- - -After that, we just create and return the `IndexedMap`: - -```rust - IndexedMap::new("tokens", indexes) -``` - -Here of course, the namespace of the pk must match the one used during index(es) creation. And, we pass our -`TokenIndexes` (as an `IndexList`-type parameter) as second argument. Connecting in this way the underlying `Map` -for the pk, with the defined indexes. - -So, `IndexedMap` (and the other `Indexed*` types) is just a wrapper / extension around `Map`, that provides -a number of index functions and namespaces to create indexes over the original `Map` data. It also implements -calling these index functions during value storage / update / removal, so that you can forget about it, -and just use the indexed data. - -### Usage - -An example of use, where `owner` is a `String` value passed as a parameter, and `start_after` and `limit` optionally -define the pagination range: - -Notice this uses `prefix()`, explained above in the `Map` section. - -```rust - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); - let owner_addr = deps.api.addr_validate(&owner)?; - - let res: Result, _> = tokens() - .idx - .owner - .prefix(owner_addr) - .range(deps.storage, start, None, Order::Ascending) - .take(limit) - .collect(); - let tokens = res?; -``` -Now `tokens` contains `(token_id, TokenInfo)` pairs for the given `owner`. -The pk values are `Vec` in the case of `range_raw()`, but will be deserialized to the proper type using -`range()`; provided that the pk deserialization type (`String`, in this case) is correctly specified -in the `MultiIndex` definition (see [Index keys deserialization](#index-keys-deserialization), -below). - -Another example that is similar, but returning only the (raw) `token_id`s, using the `keys_raw()` method: -```rust - let pks: Vec<_> = tokens() - .idx - .owner - .prefix(owner_addr) - .keys_raw( - deps.storage, - start, - None, - Order::Ascending, - ) - .take(limit) - .collect(); -``` -Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `keys` instead, -a deserialized key can be obtained, as detailed in the next section. - -### Index keys deserialization - -For `UniqueIndex` and `MultiIndex`, the primary key (`PK`) type needs to be specified, in order to deserialize -the primary key to it. -This `PK` type specification is also important for `MultiIndex` type-safe bounds, as the primary key -is part of the multi-index key. See next section, [Type-safe bounds over MultiIndex](#type-safe-bounds-over-multiindex). - -**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will (if possible) -be automated in the future (https://github.com/CosmWasm/cw-plus/issues/531). - -### Type-safe bounds over MultiIndex - -In the particular case of `MultiIndex`, the primary key (`PK`) type parameter also defines the type of the (partial) bounds over -the index key (the part that corresponds to the primary key, that is). -So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type -to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. From 5a5b173a00297728a4a14f97fe47d689aa1ce6a8 Mon Sep 17 00:00:00 2001 From: Pakorn Nathong Date: Wed, 6 Jul 2022 22:43:21 +0700 Subject: [PATCH 364/631] move struct position to cover code coverage --- packages/storage-macro/tests/index_list.rs | 39 ++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs index 3a192691b..13ee1985e 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-macro/tests/index_list.rs @@ -3,21 +3,21 @@ use cw_storage_macro::index_list; use cw_storage_plus::{IndexedMap, MultiIndex, UniqueIndex}; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct TestStruct { - id: u64, - id2: u32, - addr: Addr, -} - -#[index_list(TestStruct)] -struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, -} - #[test] fn compile() { + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + struct TestStruct { + id: u64, + id2: u32, + addr: Addr, + } + + #[index_list(TestStruct)] + struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, + } + let _: IndexedMap = IndexedMap::new( "t", TestIndexes { @@ -29,6 +29,19 @@ fn compile() { #[test] fn works() { + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + struct TestStruct { + id: u64, + id2: u32, + addr: Addr, + } + + #[index_list(TestStruct)] + struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, + } + let mut storage = MockStorage::new(); let idm: IndexedMap = IndexedMap::new( "t", From 3f29e20cf1f39edc924b62e0d0296cfdb61f5f1b Mon Sep 17 00:00:00 2001 From: Pakorn Nathong Date: Wed, 6 Jul 2022 22:49:30 +0700 Subject: [PATCH 365/631] remove macro crate features --- packages/storage-macro/Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index 75cd97aa5..d8b8ac754 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -9,10 +9,6 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" -[features] -default = ["iterator"] -iterator = ["cosmwasm-std/iterator"] - [lib] proc-macro = true From 049bcb0aa618d24d553871bcf0cd92a8e8e2d00d Mon Sep 17 00:00:00 2001 From: yoisha <48324733+y-pakorn@users.noreply.github.com> Date: Sun, 17 Jul 2022 20:51:38 +0700 Subject: [PATCH 366/631] Apply suggestions from code review Co-authored-by: Mauro Lacy --- packages/storage-macro/Cargo.toml | 2 +- packages/storage-macro/NOTICE | 4 ++-- packages/storage-macro/README.md | 6 +++--- packages/storage-macro/tests/index_list.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index d8b8ac754..b29a59f10 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -3,7 +3,7 @@ name = "cw-storage-macro" version = "0.13.4" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" -description = "Macro helper for storage package" +description = "Macro helpers for storage-plus" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" diff --git a/packages/storage-macro/NOTICE b/packages/storage-macro/NOTICE index a2d3c8655..4ae1ccfe5 100644 --- a/packages/storage-macro/NOTICE +++ b/packages/storage-macro/NOTICE @@ -1,5 +1,5 @@ -CW-Storage-Macro: Macro helper for storage package -Copyright (C) 2020 Confio OÜ +CW-Storage-Macro: Macro helpers for storage-plus +Copyright (C) 2022 Confio GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/storage-macro/README.md b/packages/storage-macro/README.md index 200c2dfa4..d21d9f571 100644 --- a/packages/storage-macro/README.md +++ b/packages/storage-macro/README.md @@ -1,10 +1,10 @@ -# CW-Storage-Plus: Macro helper for storage package +# CW-Storage-Plus: Macro helpers for storage-plus Procedural macros helper for interacting with cw-storage-plus and cosmwasm-storage. ## Current features -Auto generate IndexList impl for your indexes struct. +Auto generate an `IndexList` impl for your indexes struct. ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -14,7 +14,7 @@ struct TestStruct { addr: Addr, } -#[index_list(TestStruct)] // <- Add this line right here,. +#[index_list(TestStruct)] // <- Add this line right here. struct TestIndexes<'a> { id: MultiIndex<'a, u32, TestStruct, u64>, addr: UniqueIndex<'a, Addr, TestStruct>, diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs index 13ee1985e..7f063f532 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-macro/tests/index_list.rs @@ -21,7 +21,7 @@ fn compile() { let _: IndexedMap = IndexedMap::new( "t", TestIndexes { - id: MultiIndex::new(|t| t.id2, "t", "t_2"), + id: MultiIndex::new(|t| t.id2, "t", "t_id2"), addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), }, ); From 07f6cacc9e2ebfe1e80e76921b1cf986e8f0c25a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 17 Jul 2022 19:34:25 +0200 Subject: [PATCH 367/631] Add cfg(test) / mod test to storage-macro tests --- packages/storage-macro/tests/index_list.rs | 131 +++++++++++---------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs index 7f063f532..d81120733 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-macro/tests/index_list.rs @@ -1,73 +1,76 @@ -use cosmwasm_std::{testing::MockStorage, Addr}; -use cw_storage_macro::index_list; -use cw_storage_plus::{IndexedMap, MultiIndex, UniqueIndex}; -use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod test { + use cosmwasm_std::{testing::MockStorage, Addr}; + use cw_storage_macro::index_list; + use cw_storage_plus::{IndexedMap, MultiIndex, UniqueIndex}; + use serde::{Deserialize, Serialize}; -#[test] -fn compile() { - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] - struct TestStruct { - id: u64, - id2: u32, - addr: Addr, - } - - #[index_list(TestStruct)] - struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, - } + #[test] + fn compile() { + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + struct TestStruct { + id: u64, + id2: u32, + addr: Addr, + } - let _: IndexedMap = IndexedMap::new( - "t", - TestIndexes { - id: MultiIndex::new(|t| t.id2, "t", "t_id2"), - addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), - }, - ); -} + #[index_list(TestStruct)] + struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, + } -#[test] -fn works() { - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] - struct TestStruct { - id: u64, - id2: u32, - addr: Addr, + let _: IndexedMap = IndexedMap::new( + "t", + TestIndexes { + id: MultiIndex::new(|t| t.id2, "t", "t_id2"), + addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), + }, + ); } - #[index_list(TestStruct)] - struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, - } + #[test] + fn works() { + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + struct TestStruct { + id: u64, + id2: u32, + addr: Addr, + } + + #[index_list(TestStruct)] + struct TestIndexes<'a> { + id: MultiIndex<'a, u32, TestStruct, u64>, + addr: UniqueIndex<'a, Addr, TestStruct>, + } - let mut storage = MockStorage::new(); - let idm: IndexedMap = IndexedMap::new( - "t", - TestIndexes { - id: MultiIndex::new(|t| t.id2, "t", "t_2"), - addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), - }, - ); + let mut storage = MockStorage::new(); + let idm: IndexedMap = IndexedMap::new( + "t", + TestIndexes { + id: MultiIndex::new(|t| t.id2, "t", "t_2"), + addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), + }, + ); - idm.save( - &mut storage, - 0, - &TestStruct { - id: 0, - id2: 100, - addr: Addr::unchecked("1"), - }, - ) - .unwrap(); + idm.save( + &mut storage, + 0, + &TestStruct { + id: 0, + id2: 100, + addr: Addr::unchecked("1"), + }, + ) + .unwrap(); - assert_eq!( - idm.load(&storage, 0).unwrap(), - TestStruct { - id: 0, - id2: 100, - addr: Addr::unchecked("1"), - } - ); + assert_eq!( + idm.load(&storage, 0).unwrap(), + TestStruct { + id: 0, + id2: 100, + addr: Addr::unchecked("1"), + } + ); + } } From 43ad1e8edcecf9bc85f67d534915eb9c1b9981a5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 17 Jul 2022 19:35:41 +0200 Subject: [PATCH 368/631] Rename index_list tests for clarity --- packages/storage-macro/tests/index_list.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs index d81120733..57eff5685 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-macro/tests/index_list.rs @@ -6,7 +6,7 @@ mod test { use serde::{Deserialize, Serialize}; #[test] - fn compile() { + fn index_list_compiles() { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] struct TestStruct { id: u64, @@ -30,7 +30,7 @@ mod test { } #[test] - fn works() { + fn index_list_works() { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] struct TestStruct { id: u64, From 1b13972993bbca226b7c43bbf1d2c2661af4cc35 Mon Sep 17 00:00:00 2001 From: Daniel Farina Date: Thu, 21 Jul 2022 09:17:55 -0700 Subject: [PATCH 369/631] Updated contract versions and links This PR fixes broken links for the contracts and updates them to the latest version. --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c32b553ca..c097c9aca 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,15 @@ | Contracts | Download | Docs | Coverage | |--------------------|----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| -| cw1-subkeys | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw1-whitelist | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1_whitelist.wasm) | [![Docs](https://docs.rs/cw1-whitelist/badge.svg)](https://docs.rs/cw1-whitelist) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw3-fixed-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_fixed_multisig.wasm) | [![Docs](https://docs.rs/cw3-fixed-multisig/badge.svg)](https://docs.rs/cw3-fixed-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw3-flex-multisig | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw3_flex_multisig.wasm) | [![Docs](https://docs.rs/cw3-flex-multisig/badge.svg)](https://docs.rs/cw3-flex-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw4-group | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_group.wasm) | [![Docs](https://docs.rs/cw4-group/badge.svg)](https://docs.rs/cw4-group) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw4-stake | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw20-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw20-ics20 | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw1155-base | [Release v0.10.3](https://github.com/CosmWasm/cw-plus/releases/download/v0.10.3/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1-subkeys | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1-whitelist | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_whitelist.wasm) | [![Docs](https://docs.rs/cw1-whitelist/badge.svg)](https://docs.rs/cw1-whitelist) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3-fixed-multisig | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw3_fixed_multisig.wasm) | [![Docs](https://docs.rs/cw3-fixed-multisig/badge.svg)](https://docs.rs/cw3-fixed-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3-flex-multisig | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw3_flex_multisig.wasm) | [![Docs](https://docs.rs/cw3-flex-multisig/badge.svg)](https://docs.rs/cw3-flex-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4-group | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw4_group.wasm) | [![Docs](https://docs.rs/cw4-group/badge.svg)](https://docs.rs/cw4-group) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4-stake | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20-ics20 | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw1155-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be followed there. From af7e65c94e0e9f01b4403b9473ff22014c40b329 Mon Sep 17 00:00:00 2001 From: Ishaan Hiranandani Date: Thu, 24 Mar 2022 21:47:59 -0400 Subject: [PATCH 370/631] add query_this_hook to hooks.rs --- packages/controllers/src/hooks.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index 673b8c8de..b6d2d4d6b 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -121,6 +121,19 @@ impl<'a> Hooks<'a> { let hooks = hooks.into_iter().map(String::from).collect(); Ok(HooksResponse { hooks }) } + + // Returns true is this_hook is in hooks; false otherwiseq + pub fn query_this_hook(&self, deps: Deps, this_hook: String) -> StdResult { + let hooks = self.query_hooks(deps)?; + + for i in 0..hooks.hooks.len() { + if hooks.hooks[i] == this_hook + { + return Ok(true); + } + } + return Ok(false); + } } // TODO: add test coverage From 3f5f567789214d26f182b9031e6a09cf986bd782 Mon Sep 17 00:00:00 2001 From: Ishaan Hiranandani <51675727+ishaanh@users.noreply.github.com> Date: Fri, 25 Mar 2022 10:02:24 -0400 Subject: [PATCH 371/631] Update packages/controllers/src/hooks.rs Co-authored-by: Jakub Bogucki --- packages/controllers/src/hooks.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index b6d2d4d6b..06beae098 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -123,16 +123,16 @@ impl<'a> Hooks<'a> { } // Returns true is this_hook is in hooks; false otherwiseq - pub fn query_this_hook(&self, deps: Deps, this_hook: String) -> StdResult { - let hooks = self.query_hooks(deps)?; - - for i in 0..hooks.hooks.len() { - if hooks.hooks[i] == this_hook - { - return Ok(true); - } - } - return Ok(false); + pub fn query_this_hook( + &self, + deps: Deps, + this_hook: String, + ) -> StdResult { + Ok(self + .query_hooks(deps)? + .hooks + .into_iter() + .any(|hook| hook == this_hook)) } } From 0cb8ca78fb13ff9e9b53ca04527e681e952c5274 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 24 Jul 2022 09:15:24 +0200 Subject: [PATCH 372/631] Update comment Co-authored-by: Jakub Bogucki --- packages/controllers/src/hooks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index 06beae098..faad3699f 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -122,7 +122,7 @@ impl<'a> Hooks<'a> { Ok(HooksResponse { hooks }) } - // Returns true is this_hook is in hooks; false otherwiseq + // Returns true is this_hook is in hooks pub fn query_this_hook( &self, deps: Deps, From 956906d72969a537deac509a1919db26f765a9fd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 24 Jul 2022 09:27:40 +0200 Subject: [PATCH 373/631] cargo fmt --- packages/controllers/src/hooks.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index faad3699f..f01f33427 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -122,17 +122,9 @@ impl<'a> Hooks<'a> { Ok(HooksResponse { hooks }) } - // Returns true is this_hook is in hooks - pub fn query_this_hook( - &self, - deps: Deps, - this_hook: String, - ) -> StdResult { - Ok(self - .query_hooks(deps)? - .hooks - .into_iter() - .any(|hook| hook == this_hook)) + // Returns true if hook is in hooks + pub fn query_hook(&self, deps: Deps, hook: String) -> StdResult { + Ok(self.query_hooks(deps)?.hooks.into_iter().any(|h| h == hook)) } } From 46e9d0b0c1aba94aadc33dd40217d72b39b69f8e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sun, 24 Jul 2022 09:28:06 +0200 Subject: [PATCH 374/631] Fix syntax --- packages/controllers/src/hooks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index f01f33427..e56985c25 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -122,7 +122,7 @@ impl<'a> Hooks<'a> { Ok(HooksResponse { hooks }) } - // Returns true if hook is in hooks + // Return true if hook is in hooks pub fn query_hook(&self, deps: Deps, hook: String) -> StdResult { Ok(self.query_hooks(deps)?.hooks.into_iter().any(|h| h == hook)) } From 4bf702b399c22492a16be585d6c5b37d1e97bfb7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 13:31:05 +0200 Subject: [PATCH 375/631] Add allowances per spender map --- contracts/cw20-base/src/allowances.rs | 37 ++++++++++++++++----------- contracts/cw20-base/src/enumerable.rs | 27 ++++++++++++++++++- contracts/cw20-base/src/state.rs | 3 +++ 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 663d80820..37dcbf459 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ use cw20::{AllowanceResponse, Cw20ReceiveMsg, Expiration}; use crate::error::ContractError; -use crate::state::{ALLOWANCES, BALANCES, TOKEN_INFO}; +use crate::state::{ALLOWANCES, ALLOWANCES_SPENDER, BALANCES, TOKEN_INFO}; pub fn execute_increase_allowance( deps: DepsMut, @@ -20,18 +20,16 @@ pub fn execute_increase_allowance( return Err(ContractError::CannotSetOwnAccount {}); } - ALLOWANCES.update( - deps.storage, - (&info.sender, &spender_addr), - |allow| -> StdResult<_> { - let mut val = allow.unwrap_or_default(); - if let Some(exp) = expires { - val.expires = exp; - } - val.allowance += amount; - Ok(val) - }, - )?; + let update_fn = |allow: Option| -> StdResult<_> { + let mut val = allow.unwrap_or_default(); + if let Some(exp) = expires { + val.expires = exp; + } + val.allowance += amount; + Ok(val) + }; + ALLOWANCES.update(deps.storage, (&info.sender, &spender_addr), update_fn)?; + ALLOWANCES_SPENDER.update(deps.storage, (&spender_addr, &info.sender), update_fn)?; let res = Response::new().add_attributes(vec![ attr("action", "increase_allowance"), @@ -56,6 +54,11 @@ pub fn execute_decrease_allowance( } let key = (&info.sender, &spender_addr); + + fn reverse<'a>(t: (&'a Addr, &'a Addr)) -> (&'a Addr, &'a Addr) { + (t.1, t.0) + } + // load value and delete if it hits 0, or update otherwise let mut allowance = ALLOWANCES.load(deps.storage, key)?; if amount < allowance.allowance { @@ -68,8 +71,10 @@ pub fn execute_decrease_allowance( allowance.expires = exp; } ALLOWANCES.save(deps.storage, key, &allowance)?; + ALLOWANCES_SPENDER.save(deps.storage, reverse(key), &allowance)?; } else { ALLOWANCES.remove(deps.storage, key); + ALLOWANCES_SPENDER.remove(deps.storage, reverse(key)); } let res = Response::new().add_attributes(vec![ @@ -89,7 +94,7 @@ pub fn deduct_allowance( block: &BlockInfo, amount: Uint128, ) -> Result { - ALLOWANCES.update(storage, (owner, spender), |current| { + let update_fn = |current: Option| -> _ { match current { Some(mut a) => { if a.expires.is_expired(block) { @@ -105,7 +110,9 @@ pub fn deduct_allowance( } None => Err(ContractError::NoAllowance {}), } - }) + }; + ALLOWANCES.update(storage, (owner, spender), update_fn)?; + ALLOWANCES_SPENDER.update(storage, (spender, owner), update_fn) } pub fn execute_transfer_from( diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 7f7991c93..111b96eb7 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -1,7 +1,7 @@ use cosmwasm_std::{Deps, Order, StdResult}; use cw20::{AllAccountsResponse, AllAllowancesResponse, AllowanceInfo}; -use crate::state::{ALLOWANCES, BALANCES}; +use crate::state::{ALLOWANCES, ALLOWANCES_SPENDER, BALANCES}; use cw_storage_plus::Bound; // settings for pagination @@ -33,6 +33,31 @@ pub fn query_all_allowances( Ok(AllAllowancesResponse { allowances }) } +pub fn query_allowances_by_spender( + deps: Deps, + spender: String, + start_after: Option, + limit: Option, +) -> StdResult { + let spender_addr = deps.api.addr_validate(&spender)?; + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into_bytes())); + + let allowances = ALLOWANCES_SPENDER + .prefix(&spender_addr) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { + item.map(|(addr, allow)| AllowanceInfo { + spender: addr.into(), + allowance: allow.allowance, + expires: allow.expires, + }) + }) + .collect::>()?; + Ok(AllAllowancesResponse { allowances }) +} + pub fn query_all_accounts( deps: Deps, start_after: Option, diff --git a/contracts/cw20-base/src/state.rs b/contracts/cw20-base/src/state.rs index d52f56179..5202b4911 100644 --- a/contracts/cw20-base/src/state.rs +++ b/contracts/cw20-base/src/state.rs @@ -34,3 +34,6 @@ pub const MARKETING_INFO: Item = Item::new("marketing_inf pub const LOGO: Item = Item::new("logo"); pub const BALANCES: Map<&Addr, Uint128> = Map::new("balance"); pub const ALLOWANCES: Map<(&Addr, &Addr), AllowanceResponse> = Map::new("allowance"); +// TODO: After https://github.com/CosmWasm/cw-plus/issues/670 is implemented, replace this with a `MultiIndex` over `ALLOWANCES` +pub const ALLOWANCES_SPENDER: Map<(&Addr, &Addr), AllowanceResponse> = + Map::new("allowance_spender"); From e9c83a387388a93d34ce0965f138dbd71775339a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 15:38:07 +0200 Subject: [PATCH 376/631] Add new spender allowances structs --- packages/cw20/src/lib.rs | 2 +- packages/cw20/src/query.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/cw20/src/lib.rs b/packages/cw20/src/lib.rs index f5a142b27..56305fad4 100644 --- a/packages/cw20/src/lib.rs +++ b/packages/cw20/src/lib.rs @@ -7,7 +7,7 @@ pub use crate::helpers::Cw20Contract; pub use crate::logo::{EmbeddedLogo, Logo, LogoInfo}; pub use crate::msg::Cw20ExecuteMsg; pub use crate::query::{ - AllAccountsResponse, AllAllowancesResponse, AllowanceInfo, AllowanceResponse, BalanceResponse, + AllAccountsResponse, AllAllowancesResponse, AllowanceInfo, SpenderAllowanceInfo, AllowanceResponse, AllSpenderAllowancesResponse, BalanceResponse, Cw20QueryMsg, DownloadLogoResponse, MarketingInfoResponse, MinterResponse, TokenInfoResponse, }; pub use crate::receiver::Cw20ReceiveMsg; diff --git a/packages/cw20/src/query.rs b/packages/cw20/src/query.rs index 747db132a..84ab604b1 100644 --- a/packages/cw20/src/query.rs +++ b/packages/cw20/src/query.rs @@ -110,6 +110,18 @@ pub struct AllAllowancesResponse { pub allowances: Vec, } +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +pub struct SpenderAllowanceInfo { + pub owner: String, + pub allowance: Uint128, + pub expires: Expiration, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +pub struct AllSpenderAllowancesResponse { + pub allowances: Vec, +} + #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] pub struct AllAccountsResponse { pub accounts: Vec, From 15f929a542e0ec03d1ce01559df8a595447cc55e Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 15:39:22 +0200 Subject: [PATCH 377/631] Add new AllSpendersAllowances query --- contracts/cw20-base/src/contract.rs | 14 ++++- contracts/cw20-base/src/enumerable.rs | 88 +++++++++++++++++++++++---- contracts/cw20-base/src/msg.rs | 8 +++ 3 files changed, 97 insertions(+), 13 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index eeece2818..dd3e8dac5 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -14,7 +14,7 @@ use crate::allowances::{ execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from, execute_transfer_from, query_allowance, }; -use crate::enumerable::{query_all_accounts, query_all_allowances}; +use crate::enumerable::{query_all_accounts, query_owner_allowances, query_spender_allowances}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{MinterData, TokenInfo, BALANCES, LOGO, MARKETING_INFO, TOKEN_INFO}; @@ -528,7 +528,17 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { owner, start_after, limit, - } => to_binary(&query_all_allowances(deps, owner, start_after, limit)?), + } => to_binary(&query_owner_allowances(deps, owner, start_after, limit)?), + QueryMsg::AllSpenderAllowances { + spender, + start_after, + limit, + } => to_binary(&query_spender_allowances( + deps, + spender, + start_after, + limit, + )?), QueryMsg::AllAccounts { start_after, limit } => { to_binary(&query_all_accounts(deps, start_after, limit)?) } diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 111b96eb7..6af04d7b2 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -1,5 +1,8 @@ use cosmwasm_std::{Deps, Order, StdResult}; -use cw20::{AllAccountsResponse, AllAllowancesResponse, AllowanceInfo}; +use cw20::{ + AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceInfo, + SpenderAllowanceInfo, +}; use crate::state::{ALLOWANCES, ALLOWANCES_SPENDER, BALANCES}; use cw_storage_plus::Bound; @@ -8,7 +11,7 @@ use cw_storage_plus::Bound; const MAX_LIMIT: u32 = 30; const DEFAULT_LIMIT: u32 = 10; -pub fn query_all_allowances( +pub fn query_owner_allowances( deps: Deps, owner: String, start_after: Option, @@ -33,12 +36,12 @@ pub fn query_all_allowances( Ok(AllAllowancesResponse { allowances }) } -pub fn query_allowances_by_spender( +pub fn query_spender_allowances( deps: Deps, spender: String, start_after: Option, limit: Option, -) -> StdResult { +) -> StdResult { let spender_addr = deps.api.addr_validate(&spender)?; let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.map(|s| Bound::ExclusiveRaw(s.into_bytes())); @@ -48,14 +51,14 @@ pub fn query_allowances_by_spender( .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| { - item.map(|(addr, allow)| AllowanceInfo { - spender: addr.into(), + item.map(|(addr, allow)| SpenderAllowanceInfo { + owner: addr.into(), allowance: allow.allowance, expires: allow.expires, }) }) .collect::>()?; - Ok(AllAllowancesResponse { allowances }) + Ok(AllSpenderAllowancesResponse { allowances }) } pub fn query_all_accounts( @@ -119,7 +122,7 @@ mod tests { do_instantiate(deps.as_mut(), &owner, Uint128::new(12340000)); // no allowance to start - let allowances = query_all_allowances(deps.as_ref(), owner.clone(), None, None).unwrap(); + let allowances = query_owner_allowances(deps.as_ref(), owner.clone(), None, None).unwrap(); assert_eq!(allowances.allowances, vec![]); // set allowance with height expiration @@ -142,11 +145,12 @@ mod tests { execute(deps.as_mut(), env, info, msg).unwrap(); // query list gets 2 - let allowances = query_all_allowances(deps.as_ref(), owner.clone(), None, None).unwrap(); + let allowances = query_owner_allowances(deps.as_ref(), owner.clone(), None, None).unwrap(); assert_eq!(allowances.allowances.len(), 2); // first one is spender1 (order of CanonicalAddr uncorrelated with String) - let allowances = query_all_allowances(deps.as_ref(), owner.clone(), None, Some(1)).unwrap(); + let allowances = + query_owner_allowances(deps.as_ref(), owner.clone(), None, Some(1)).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; assert_eq!(&allow.spender, &spender1); @@ -154,7 +158,7 @@ mod tests { assert_eq!(&allow.allowance, &allow1); // next one is spender2 - let allowances = query_all_allowances( + let allowances = query_owner_allowances( deps.as_ref(), owner, Some(allow.spender.clone()), @@ -168,6 +172,68 @@ mod tests { assert_eq!(&allow.allowance, &allow2); } + #[test] + fn query_allowances_by_spender_works() { + let mut deps = mock_dependencies_with_balance(&coins(2, "token")); + + let owner = String::from("owner"); + // these are in alphabetical order same than insert order + let spender1 = String::from("earlier"); + let spender2 = String::from("later"); + + let info = mock_info(owner.as_ref(), &[]); + let env = mock_env(); + do_instantiate(deps.as_mut(), &owner, Uint128::new(12340000)); + + // no allowance to start + let allowances = + query_spender_allowances(deps.as_ref(), spender1.clone(), None, None).unwrap(); + assert_eq!(allowances.allowances, vec![]); + let allowances = + query_spender_allowances(deps.as_ref(), spender2.clone(), None, None).unwrap(); + assert_eq!(allowances.allowances, vec![]); + + // set allowance with height expiration + let allow1 = Uint128::new(7777); + let expires = Expiration::AtHeight(5432); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender1.clone(), + amount: allow1, + expires: Some(expires), + }; + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + // set allowance with no expiration + let allow2 = Uint128::new(54321); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender2.clone(), + amount: allow2, + expires: None, + }; + execute(deps.as_mut(), env, info, msg).unwrap(); + + // query list gets 1 each + let allowances = + query_spender_allowances(deps.as_ref(), spender1.clone(), None, None).unwrap(); + assert_eq!(allowances.allowances.len(), 1); + let allowances = + query_spender_allowances(deps.as_ref(), spender2.clone(), None, None).unwrap(); + assert_eq!(allowances.allowances.len(), 1); + + // one is just owner (order of CanonicalAddr uncorrelated with String) + let allowances = query_spender_allowances(deps.as_ref(), spender1, None, Some(1)).unwrap(); + assert_eq!(allowances.allowances.len(), 1); + let allow = &allowances.allowances[0]; + assert_eq!(&allow.owner, &owner); + assert_eq!(&allow.expires, &expires); + assert_eq!(&allow.allowance, &allow1); + + // other one is also owner (start_after works) + let allowances = + query_spender_allowances(deps.as_ref(), spender2, Some(owner), Some(10000)).unwrap(); + assert_eq!(allowances.allowances.len(), 0); + } + #[test] fn query_all_accounts_works() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index 0cb18227a..e2d4239d5 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -93,6 +93,14 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + /// Only with "enumerable" extension (and "allowances") + /// Returns all allowances this spender has been granted. Supports pagination. + /// Return type: AllSpenderAllowancesResponse. + AllSpenderAllowances { + spender: String, + start_after: Option, + limit: Option, + }, /// Only with "enumerable" extension /// Returns all accounts that have balances. Supports pagination. /// Return type: AllAccountsResponse. From 86afbb4cfdde17a98085a80fc0baabf37a420bb2 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 15:40:15 +0200 Subject: [PATCH 378/631] Add AllSpenderAllowancesResponse to schema --- contracts/cw20-base/examples/schema.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-base/examples/schema.rs b/contracts/cw20-base/examples/schema.rs index 0afc8144c..e715901a6 100644 --- a/contracts/cw20-base/examples/schema.rs +++ b/contracts/cw20-base/examples/schema.rs @@ -4,8 +4,8 @@ use std::fs::create_dir_all; use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; use cw20::{ - AllAccountsResponse, AllAllowancesResponse, AllowanceResponse, BalanceResponse, - TokenInfoResponse, + AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceResponse, + BalanceResponse, TokenInfoResponse, }; use cw20_base::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -22,5 +22,6 @@ fn main() { export_schema(&schema_for!(BalanceResponse), &out_dir); export_schema(&schema_for!(TokenInfoResponse), &out_dir); export_schema(&schema_for!(AllAllowancesResponse), &out_dir); + export_schema(&schema_for!(AllSpenderAllowancesResponse), &out_dir); export_schema(&schema_for!(AllAccountsResponse), &out_dir); } From 131c7b994b25e64acd5a4d2aa37323bbfeda1434 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 15:47:36 +0200 Subject: [PATCH 379/631] Fix / improve spender allowances test --- contracts/cw20-base/src/enumerable.rs | 57 ++++++++++++++------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 6af04d7b2..b917a5794 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -109,7 +109,7 @@ mod tests { } #[test] - fn query_all_allowances_works() { + fn query_all_owner_allowances_works() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); let owner = String::from("owner"); @@ -173,65 +173,68 @@ mod tests { } #[test] - fn query_allowances_by_spender_works() { + fn query_all_spender_allowances_works() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("owner"); // these are in alphabetical order same than insert order - let spender1 = String::from("earlier"); - let spender2 = String::from("later"); + let owner1 = String::from("owner1"); + let owner2 = String::from("owner2"); + let spender = String::from("spender"); - let info = mock_info(owner.as_ref(), &[]); + let info = mock_info(owner1.as_ref(), &[]); let env = mock_env(); - do_instantiate(deps.as_mut(), &owner, Uint128::new(12340000)); + do_instantiate(deps.as_mut(), &owner1, Uint128::new(12340000)); // no allowance to start let allowances = - query_spender_allowances(deps.as_ref(), spender1.clone(), None, None).unwrap(); - assert_eq!(allowances.allowances, vec![]); - let allowances = - query_spender_allowances(deps.as_ref(), spender2.clone(), None, None).unwrap(); + query_spender_allowances(deps.as_ref(), spender.clone(), None, None).unwrap(); assert_eq!(allowances.allowances, vec![]); // set allowance with height expiration let allow1 = Uint128::new(7777); let expires = Expiration::AtHeight(5432); let msg = ExecuteMsg::IncreaseAllowance { - spender: spender1.clone(), + spender: spender.clone(), amount: allow1, expires: Some(expires), }; - execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + execute(deps.as_mut(), env, info, msg).unwrap(); + + // set allowance with no expiration, from the other owner + let info = mock_info(owner2.as_ref(), &[]); + let env = mock_env(); + do_instantiate(deps.as_mut(), &owner2, Uint128::new(12340000)); - // set allowance with no expiration let allow2 = Uint128::new(54321); let msg = ExecuteMsg::IncreaseAllowance { - spender: spender2.clone(), + spender: spender.clone(), amount: allow2, expires: None, }; execute(deps.as_mut(), env, info, msg).unwrap(); - // query list gets 1 each - let allowances = - query_spender_allowances(deps.as_ref(), spender1.clone(), None, None).unwrap(); - assert_eq!(allowances.allowances.len(), 1); + // query list gets both let allowances = - query_spender_allowances(deps.as_ref(), spender2.clone(), None, None).unwrap(); - assert_eq!(allowances.allowances.len(), 1); + query_spender_allowances(deps.as_ref(), spender.clone(), None, None).unwrap(); + assert_eq!(allowances.allowances.len(), 2); - // one is just owner (order of CanonicalAddr uncorrelated with String) - let allowances = query_spender_allowances(deps.as_ref(), spender1, None, Some(1)).unwrap(); + // one is owner1 (order of CanonicalAddr uncorrelated with String) + let allowances = + query_spender_allowances(deps.as_ref(), spender.clone(), None, Some(1)).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; - assert_eq!(&allow.owner, &owner); + assert_eq!(&allow.owner, &owner1); assert_eq!(&allow.expires, &expires); assert_eq!(&allow.allowance, &allow1); - // other one is also owner (start_after works) + // other one is owner2 let allowances = - query_spender_allowances(deps.as_ref(), spender2, Some(owner), Some(10000)).unwrap(); - assert_eq!(allowances.allowances.len(), 0); + query_spender_allowances(deps.as_ref(), spender, Some(owner1), Some(10000)).unwrap(); + assert_eq!(allowances.allowances.len(), 1); + let allow = &allowances.allowances[0]; + assert_eq!(&allow.owner, &owner2); + assert_eq!(&allow.expires, &Expiration::Never {}); + assert_eq!(&allow.allowance, &allow2); } #[test] From 30e4a97e948a4a5facc33e5796b0070591e1616f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 15:55:56 +0200 Subject: [PATCH 380/631] cargo fmt --- packages/cw20/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cw20/src/lib.rs b/packages/cw20/src/lib.rs index 56305fad4..034d5de72 100644 --- a/packages/cw20/src/lib.rs +++ b/packages/cw20/src/lib.rs @@ -7,8 +7,9 @@ pub use crate::helpers::Cw20Contract; pub use crate::logo::{EmbeddedLogo, Logo, LogoInfo}; pub use crate::msg::Cw20ExecuteMsg; pub use crate::query::{ - AllAccountsResponse, AllAllowancesResponse, AllowanceInfo, SpenderAllowanceInfo, AllowanceResponse, AllSpenderAllowancesResponse, BalanceResponse, - Cw20QueryMsg, DownloadLogoResponse, MarketingInfoResponse, MinterResponse, TokenInfoResponse, + AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceInfo, + AllowanceResponse, BalanceResponse, Cw20QueryMsg, DownloadLogoResponse, MarketingInfoResponse, + MinterResponse, SpenderAllowanceInfo, TokenInfoResponse, }; pub use crate::receiver::Cw20ReceiveMsg; From 5cdbbe96a1050319a9bf1f49119c84d18210f531 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 21 Jul 2022 17:19:18 +0200 Subject: [PATCH 381/631] Build reverse allowances map during migration --- contracts/cw20-base/src/contract.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index dd3e8dac5..e0fcd18dd 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -1,5 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; +use cosmwasm_std::Order::Ascending; use cosmwasm_std::{ to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; @@ -17,7 +18,10 @@ use crate::allowances::{ use crate::enumerable::{query_all_accounts, query_owner_allowances, query_spender_allowances}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{MinterData, TokenInfo, BALANCES, LOGO, MARKETING_INFO, TOKEN_INFO}; +use crate::state::{ + MinterData, TokenInfo, ALLOWANCES, ALLOWANCES_SPENDER, BALANCES, LOGO, MARKETING_INFO, + TOKEN_INFO, +}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw20-base"; @@ -598,7 +602,14 @@ pub fn query_download_logo(deps: Deps) -> StdResult { } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Build reverse map of allowances per spender + let data = ALLOWANCES + .range(deps.storage, None, None, Ascending) + .collect::>>()?; + for ((owner, spender), allowance) in data { + ALLOWANCES_SPENDER.save(deps.storage, (&spender, &owner), &allowance)?; + } Ok(Response::default()) } From 62041bcaac2d7ed60bdd1462fa85ebf5b62e786b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 22 Jul 2022 09:27:32 +0200 Subject: [PATCH 382/631] Add migration utils to utils package --- packages/utils/Cargo.toml | 4 ++ packages/utils/src/lib.rs | 2 + packages/utils/src/migrate.rs | 86 +++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 packages/utils/src/migrate.rs diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 8817637d6..2c8ec3baf 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,7 +12,11 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } + +cw2 = { path = "../../packages/cw2", version = "0.13.4" } + schemars = "0.8.1" +semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index 4687606d9..cf60d22c7 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,12 +1,14 @@ mod balance; mod event; mod expiration; +mod migrate; mod pagination; mod parse_reply; mod payment; mod scheduled; mod threshold; +pub use migrate::ensure_from_older_version; pub use pagination::{ calc_range_end, calc_range_start, calc_range_start_string, maybe_addr, maybe_canonical, }; diff --git a/packages/utils/src/migrate.rs b/packages/utils/src/migrate.rs new file mode 100644 index 000000000..9e89bc3e9 --- /dev/null +++ b/packages/utils/src/migrate.rs @@ -0,0 +1,86 @@ +use cosmwasm_std::{StdError, StdResult, Storage}; +use cw2::{get_contract_version, set_contract_version}; +use semver::Version; + +pub fn ensure_from_older_version( + storage: &mut dyn Storage, + name: &str, + new_version: &str, +) -> StdResult { + let version: Version = new_version.parse().map_err(from_semver)?; + let stored = get_contract_version(storage)?; + let storage_version: Version = stored.version.parse().map_err(from_semver)?; + + if name != stored.contract { + let msg = format!("Cannot migrate from {} to {}", stored.contract, name); + return Err(StdError::generic_err(msg)); + } + + if storage_version > version { + let msg = format!( + "Cannot migrate from newer version ({}) to older ({})", + stored.version, new_version + ); + return Err(StdError::generic_err(msg)); + } + if storage_version < version { + // we don't need to save anything if migrating from the same version + set_contract_version(storage, name, new_version)?; + } + + Ok(storage_version) +} + +fn from_semver(err: semver::Error) -> StdError { + StdError::generic_err(format!("Semver: {}", err)) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::MockStorage; + + #[test] + fn accepts_identical_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); + // ensure this matches + ensure_from_older_version(&mut storage, "demo", "0.1.2").unwrap(); + } + + #[test] + fn accepts_and_updates_on_newer_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.4.0").unwrap(); + // ensure this matches + let original_version = ensure_from_older_version(&mut storage, "demo", "0.4.2").unwrap(); + + // check the original version is returned + assert_eq!(original_version.to_string(), "0.4.0".to_string()); + + // check the version is updated + let stored = get_contract_version(&storage).unwrap(); + assert_eq!(stored.contract, "demo".to_string()); + assert_eq!(stored.version, "0.4.2".to_string()); + } + + #[test] + fn errors_on_name_mismatch() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); + // ensure this matches + let err = ensure_from_older_version(&mut storage, "cw20-base", "0.1.2").unwrap_err(); + assert!(err.to_string().contains("cw20-base"), "{}", err); + assert!(err.to_string().contains("demo"), "{}", err); + } + + #[test] + fn errors_on_older_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.10.2").unwrap(); + // ensure this matches + let err = ensure_from_older_version(&mut storage, "demo", "0.9.7").unwrap_err(); + assert!(err.to_string().contains("0.10.2"), "{}", err); + assert!(err.to_string().contains("0.9.7"), "{}", err); + } +} From 34c77fa40cb488db32f8fa2a70192d4798df250c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 22 Jul 2022 09:29:57 +0200 Subject: [PATCH 383/631] Add version check for migrating allowances --- contracts/cw20-base/src/contract.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index e0fcd18dd..467fa74a1 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -10,6 +10,7 @@ use cw20::{ BalanceResponse, Cw20Coin, Cw20ReceiveMsg, DownloadLogoResponse, EmbeddedLogo, Logo, LogoInfo, MarketingInfoResponse, MinterResponse, TokenInfoResponse, }; +use cw_utils::ensure_from_older_version; use crate::allowances::{ execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from, @@ -603,12 +604,17 @@ pub fn query_download_logo(deps: Deps) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // Build reverse map of allowances per spender - let data = ALLOWANCES - .range(deps.storage, None, None, Ascending) - .collect::>>()?; - for ((owner, spender), allowance) in data { - ALLOWANCES_SPENDER.save(deps.storage, (&spender, &owner), &allowance)?; + let original_version = + ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + if original_version.to_string() < "0.14.0".to_string() { + // Build reverse map of allowances per spender + let data = ALLOWANCES + .range(deps.storage, None, None, Ascending) + .collect::>>()?; + for ((owner, spender), allowance) in data { + ALLOWANCES_SPENDER.save(deps.storage, (&spender, &owner), &allowance)?; + } } Ok(Response::default()) } From be9874bf879a588a5ce04de376bed07061aa91be Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 22 Jul 2022 09:30:29 +0200 Subject: [PATCH 384/631] Update lock file --- Cargo.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 011003963..781c7efc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,8 +434,10 @@ version = "0.13.4" dependencies = [ "cosmwasm-std", "cw-storage-plus", + "cw2", "prost", "schemars", + "semver", "serde", "thiserror", ] From d4e734aaa4d9bfd985a82ec7a2a74ac2f98fc9c7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 22 Jul 2022 10:33:27 +0200 Subject: [PATCH 385/631] Use semver for version comparison --- contracts/cw20-base/Cargo.toml | 1 + contracts/cw20-base/src/contract.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 38177c403..3654163b7 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -24,6 +24,7 @@ cw20 = { path = "../../packages/cw20", version = "0.13.4" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" +semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 467fa74a1..34d2ce6cb 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -607,7 +607,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result().unwrap() { // Build reverse map of allowances per spender let data = ALLOWANCES .range(deps.storage, None, None, Ascending) From 9723ae39a0986044894b754f3b29366f0d1d8c2b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 22 Jul 2022 10:33:44 +0200 Subject: [PATCH 386/631] Update lock file --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 781c7efc4..2262db822 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,6 +566,7 @@ dependencies = [ "cw2", "cw20", "schemars", + "semver", "serde", "thiserror", ] From cea3b50120f7fb5d7b67ff8ad75bdbdf98b6b3e7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 26 Jul 2022 22:32:30 +0200 Subject: [PATCH 387/631] Remove newline Co-authored-by: Jakub Bogucki --- packages/utils/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 2c8ec3baf..0c808c06e 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,9 +12,7 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } - cw2 = { path = "../../packages/cw2", version = "0.13.4" } - schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } From c779a6cf75d6a9c14d44a46a4d3d8284865a8d21 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 26 Jul 2022 22:38:05 +0200 Subject: [PATCH 388/631] Add ensure_from_older_version docstring --- packages/utils/src/migrate.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/utils/src/migrate.rs b/packages/utils/src/migrate.rs index 9e89bc3e9..eb3b8f30a 100644 --- a/packages/utils/src/migrate.rs +++ b/packages/utils/src/migrate.rs @@ -2,6 +2,9 @@ use cosmwasm_std::{StdError, StdResult, Storage}; use cw2::{get_contract_version, set_contract_version}; use semver::Version; +/// This function not only validates that the right contract and version can be migrated, but also +/// updates the contract version from the original (stored) version to the new version. +/// It returns the original version for the convenience of doing external checks. pub fn ensure_from_older_version( storage: &mut dyn Storage, name: &str, From c2ca27302452e39c133f220e6f54ca513afc9774 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 26 Jul 2022 22:52:30 +0200 Subject: [PATCH 389/631] Do spender allowances queries through query handler --- contracts/cw20-base/src/enumerable.rs | 35 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index b917a5794..8022fe9bd 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -83,11 +83,11 @@ mod tests { use super::*; use cosmwasm_std::testing::{mock_dependencies_with_balance, mock_env, mock_info}; - use cosmwasm_std::{coins, DepsMut, Uint128}; + use cosmwasm_std::{coins, from_binary, DepsMut, Uint128}; use cw20::{Cw20Coin, Expiration, TokenInfoResponse}; - use crate::contract::{execute, instantiate, query_token_info}; - use crate::msg::{ExecuteMsg, InstantiateMsg}; + use crate::contract::{execute, instantiate, query, query_token_info}; + use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; // this will set up the instantiation for other tests fn do_instantiate(mut deps: DepsMut, addr: &str, amount: Uint128) -> TokenInfoResponse { @@ -211,16 +211,26 @@ mod tests { amount: allow2, expires: None, }; - execute(deps.as_mut(), env, info, msg).unwrap(); + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); // query list gets both - let allowances = - query_spender_allowances(deps.as_ref(), spender.clone(), None, None).unwrap(); + let msg = QueryMsg::AllSpenderAllowances { + spender: spender.clone(), + start_after: None, + limit: None, + }; + let allowances: AllSpenderAllowancesResponse = + from_binary(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 2); // one is owner1 (order of CanonicalAddr uncorrelated with String) - let allowances = - query_spender_allowances(deps.as_ref(), spender.clone(), None, Some(1)).unwrap(); + let msg = QueryMsg::AllSpenderAllowances { + spender: spender.clone(), + start_after: None, + limit: Some(1), + }; + let allowances: AllSpenderAllowancesResponse = + from_binary(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; assert_eq!(&allow.owner, &owner1); @@ -228,8 +238,13 @@ mod tests { assert_eq!(&allow.allowance, &allow1); // other one is owner2 - let allowances = - query_spender_allowances(deps.as_ref(), spender, Some(owner1), Some(10000)).unwrap(); + let msg = QueryMsg::AllSpenderAllowances { + spender, + start_after: Some(owner1), + limit: Some(10000), + }; + let allowances: AllSpenderAllowancesResponse = + from_binary(&query(deps.as_ref(), env, msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; assert_eq!(&allow.owner, &owner2); From 03fdf6ba43ce1c46ab5bb788a3ea26d1fbc64925 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 27 Jul 2022 06:19:30 +0200 Subject: [PATCH 390/631] Add broken version test --- packages/utils/src/migrate.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/utils/src/migrate.rs b/packages/utils/src/migrate.rs index eb3b8f30a..e537cba5a 100644 --- a/packages/utils/src/migrate.rs +++ b/packages/utils/src/migrate.rs @@ -86,4 +86,15 @@ mod tests { assert!(err.to_string().contains("0.10.2"), "{}", err); assert!(err.to_string().contains("0.9.7"), "{}", err); } + + #[test] + fn errors_on_broken_version() { + let mut storage = MockStorage::new(); + let err = ensure_from_older_version(&mut storage, "demo", "0.a.7").unwrap_err(); + assert!( + err.to_string().contains("unexpected character 'a'"), + "{}", + err + ); + } } From ee6217d853983d6ed191342045e811577653ac11 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 27 Jul 2022 07:22:04 +0200 Subject: [PATCH 391/631] Improve migration test coverage --- contracts/cw20-base/src/contract.rs | 57 ++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 34d2ce6cb..029af5629 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -1347,7 +1347,9 @@ mod tests { use super::*; use cosmwasm_std::Empty; + use cw20::{AllAllowancesResponse, AllSpenderAllowancesResponse, SpenderAllowanceInfo}; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; + use cw_utils::Expiration; fn cw20_contract() -> Box> { let contract = ContractWrapper::new( @@ -1385,6 +1387,36 @@ mod tests { ) .unwrap(); + // no allowance to start + let allowance: AllAllowancesResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.to_string(), + &QueryMsg::AllAllowances { + owner: "sender".to_string(), + start_after: None, + limit: None, + }, + ) + .unwrap(); + assert_eq!(allowance, AllAllowancesResponse::default()); + + // Set allowance + let allow1 = Uint128::new(7777); + let expires = Expiration::AtHeight(5432); + let msg = CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: cw20_addr.to_string(), + msg: to_binary(&ExecuteMsg::IncreaseAllowance { + spender: "spender".into(), + amount: allow1, + expires: Some(expires), + }) + .unwrap(), + funds: vec![], + }); + app.execute(Addr::unchecked("sender"), msg).unwrap(); + + // Now migrate app.execute( Addr::unchecked("sender"), CosmosMsg::Wasm(WasmMsg::Migrate { @@ -1399,14 +1431,35 @@ mod tests { let balance: cw20::BalanceResponse = app .wrap() .query_wasm_smart( - cw20_addr, + cw20_addr.clone(), &QueryMsg::Balance { address: "sender".to_string(), }, ) .unwrap(); - assert_eq!(balance.balance, Uint128::new(100)) + assert_eq!(balance.balance, Uint128::new(100)); + + // Confirm that the allowance per spender is there + let allowance: AllSpenderAllowancesResponse = app + .wrap() + .query_wasm_smart( + cw20_addr, + &QueryMsg::AllSpenderAllowances { + spender: "spender".to_string(), + start_after: None, + limit: None, + }, + ) + .unwrap(); + assert_eq!( + allowance.allowances, + &[SpenderAllowanceInfo { + owner: "sender".to_string(), + allowance: allow1, + expires + }] + ); } } From 9c752ec92cb1d39a51b065f6183582694e646ad7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 27 Jul 2022 07:43:00 +0200 Subject: [PATCH 392/631] Set version: 0.14.0 --- Cargo.lock | 42 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 +++---- contracts/cw1155-base/Cargo.toml | 10 +++--- contracts/cw20-base/Cargo.toml | 12 +++---- contracts/cw20-ics20/Cargo.toml | 12 +++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 +++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-macro/Cargo.toml | 4 +-- packages/storage-plus/Cargo.toml | 4 +-- packages/utils/Cargo.toml | 6 ++-- 22 files changed, 112 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2262db822..40c190f9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,7 +379,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -391,7 +391,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.4" +version = "0.14.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "cw-storage-macro" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -418,7 +418,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-std", "criterion", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -454,7 +454,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -471,7 +471,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.13.4" +version = "0.14.0" dependencies = [ "anyhow", "assert_matches", @@ -490,7 +490,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.13.4" +version = "0.14.0" dependencies = [ "anyhow", "assert_matches", @@ -509,7 +509,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -520,7 +520,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -535,7 +535,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -556,7 +556,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -590,7 +590,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -601,7 +601,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -619,7 +619,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -638,7 +638,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -649,7 +649,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -665,7 +665,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.13.4" +version = "0.14.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 73172f4f1..8e79436f3 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw1 = { path = "../../packages/cw1", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.4", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw1 = { path = "../../packages/cw1", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library"] } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -32,4 +32,4 @@ semver = "1" [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.13.4", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index fc231f04e..eacafb300 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.13.4" +version = "0.14.0" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -22,20 +22,20 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw1 = { path = "../../packages/cw1", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw1 = { path = "../../packages/cw1", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index f1666d5fb..f9e011fc7 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw1 = { path = "../../packages/cw1", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw1 = { path = "../../packages/cw1", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } anyhow = "1" assert_matches = "1" cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index f0f0534c1..d95ed6fd8 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.13.4" +version = "0.14.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw1155 = { path = "../../packages/cw1155", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 3654163b7..d5a2b5c67 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw20 = { path = "../../packages/cw20", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw20 = { path = "../../packages/cw20", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index c5d5a59b9..51f960bb9 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw20 = { path = "../../packages/cw20", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw20 = { path = "../../packages/cw20", version = "0.14.0" } cosmwasm-std = { version = "1.0.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 5b44bee16..5986fde00 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -18,10 +18,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw3 = { path = "../../packages/cw3", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw3 = { path = "../../packages/cw3", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -29,6 +29,6 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "0.13.4" } -cw20-base = { path = "../cw20-base", version = "0.13.4", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } +cw20 = { path = "../../packages/cw20", version = "0.14.0" } +cw20-base = { path = "../cw20-base", version = "0.14.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index d829ae454..aded312db 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw3 = { path = "../../packages/cw3", version = "0.13.4" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.13.4", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw3 = { path = "../../packages/cw3", version = "0.14.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.14.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,5 +31,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } -cw4-group = { path = "../cw4-group", version = "0.13.4" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.13.4" } +cw4-group = { path = "../cw4-group", version = "0.14.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 722150a1a..3505be4b1 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -26,11 +26,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw4 = { path = "../../packages/cw4", version = "0.13.4" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw4 = { path = "../../packages/cw4", version = "0.14.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index d27c1e12e..3c330837a 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -26,12 +26,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } -cw4 = { path = "../../packages/cw4", version = "0.13.4" } -cw20 = { path = "../../packages/cw20", version = "0.13.4" } -cw-controllers = { path = "../../packages/controllers", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw4 = { path = "../../packages/cw4", version = "0.14.0" } +cw20 = { path = "../../packages/cw20", version = "0.14.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 8ae57c609..56759d389 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -12,8 +12,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } -cw-utils = { path = "../utils", version = "0.13.4" } -cw-storage-plus = { path = "../storage-plus", version = "0.13.4" } +cw-utils = { path = "../utils", version = "0.14.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 7d53ca78b..217a478ed 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 14395ae23..0ee87d3e8 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.13.4" +version = "0.14.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 955e3f33d..961ed3733 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -10,6 +10,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 20bf00178..e18423a89 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index df3a42b97..bb9532bc0 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } +cw-utils = { path = "../../packages/utils", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 800188a14..668899336 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index bae48e06b..bfc5c83cf 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -17,8 +17,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.13.4" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4"} +cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0"} cosmwasm-std = { version = "1.0.0", features = ["staking"] } cosmwasm-storage = { version = "1.0.0" } itertools = "0.10.1" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index b29a59f10..a4389f414 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-macro" -version = "0.13.4" +version = "0.14.0" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" description = "Macro helpers for storage-plus" @@ -16,6 +16,6 @@ proc-macro = true syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] -cw-storage-plus = { version = "0.13.4", path = "../storage-plus" } +cw-storage-plus = { version = "0.14.0", path = "../storage-plus" } cosmwasm-std = { version = "1.0.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 524890ef1..3d9b4a14e 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -21,7 +21,7 @@ bench = false cosmwasm-std = { version = "1.0.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.13.4", optional = true, path = "../storage-macro" } +cw-storage-macro = { version = "0.14.0", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = [ "html_reports" ] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 0c808c06e..aec23b9d7 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.13.4" +version = "0.14.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -12,12 +12,12 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-std = { version = "1.0.0" } -cw2 = { path = "../../packages/cw2", version = "0.13.4" } +cw2 = { path = "../../packages/cw2", version = "0.14.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.13.4" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } prost = "0.9" From 7faa4b7f777f8a0c0a68ce20a5780d6ae53992b8 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 27 Jul 2022 07:46:33 +0200 Subject: [PATCH 393/631] Update CHANGELOG --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5135a2c3f..4a93aeff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,40 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.4...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.14.0...HEAD) + +## [v0.14.0](https://github.com/CosmWasm/cw-plus/tree/v0.14.0) (2022-07-27) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.13.4...v0.14.0) + +**Closed issues:** + +- cw20-ics20 incorrectly encodes `ack_success`. [\#759](https://github.com/CosmWasm/cw-plus/issues/759) +- Allow querying all granted allowances to a spender [\#756](https://github.com/CosmWasm/cw-plus/issues/756) +- Store compiled wasms on repo [\#747](https://github.com/CosmWasm/cw-plus/issues/747) +- Add optional executor restriction to cw3-flex [\#739](https://github.com/CosmWasm/cw-plus/issues/739) +- Provide proc macro package for automatic `IndexList` implementation on any index struct [\#736](https://github.com/CosmWasm/cw-plus/issues/736) +- MultiIndex `prefix` and `sub_prefix` working incorrectly when using a triple element tuple as IK [\#730](https://github.com/CosmWasm/cw-plus/issues/730) +- Errors when compiling all the contracts [\#724](https://github.com/CosmWasm/cw-plus/issues/724) +- Test-specific helpers in storage-plus [\#708](https://github.com/CosmWasm/cw-plus/issues/708) **Merged pull requests:** -- Add ability to unset minter in UpdateMinter message. [\#748](https://github.com/CosmWasm/cw-plus/pull/748) ([ezekiiel](https://github.com/ezekiiel)) +- Updated contract versions and links [\#762](https://github.com/CosmWasm/cw-plus/pull/762) ([daniel-farina](https://github.com/daniel-farina)) +- Allowances per spender [\#761](https://github.com/CosmWasm/cw-plus/pull/761) ([maurolacy](https://github.com/maurolacy)) +- Fix broken links, minor typo [\#752](https://github.com/CosmWasm/cw-plus/pull/752) ([mikedotexe](https://github.com/mikedotexe)) +- Use into\_iter\(\) instead of iter\(\).cloned\(\). [\#749](https://github.com/CosmWasm/cw-plus/pull/749) ([ezekiiel](https://github.com/ezekiiel)) +- Add ability to unset minter in UpdateMinter message. [\#748](https://github.com/CosmWasm/cw-plus/pull/748) ([ezekiiel](https://github.com/ezekiiel)) +- Fix specification about CW20 Enumerable Queries [\#746](https://github.com/CosmWasm/cw-plus/pull/746) ([lukepark327](https://github.com/lukepark327)) +- Add migrate method to cw20 base. [\#745](https://github.com/CosmWasm/cw-plus/pull/745) ([ezekiiel](https://github.com/ezekiiel)) +- Add optional executor restriction to cw3-flex [\#741](https://github.com/CosmWasm/cw-plus/pull/741) ([ueco-jb](https://github.com/ueco-jb)) +- Add proc macro package for automatic `IndexList` implementation [\#737](https://github.com/CosmWasm/cw-plus/pull/737) ([y-pakorn](https://github.com/y-pakorn)) +- Bump workspace-optimizer version in README to `0.12.6` [\#735](https://github.com/CosmWasm/cw-plus/pull/735) ([uint](https://github.com/uint)) +- Use standard CosmosMsg [\#734](https://github.com/CosmWasm/cw-plus/pull/734) ([ethanfrey](https://github.com/ethanfrey)) +- add execute msg to update minter [\#729](https://github.com/CosmWasm/cw-plus/pull/729) ([janitachalam](https://github.com/janitachalam)) +- Removed documentation from Cargo.toml [\#711](https://github.com/CosmWasm/cw-plus/pull/711) ([hashedone](https://github.com/hashedone)) +- Move test helpers into a test section [\#709](https://github.com/CosmWasm/cw-plus/pull/709) ([shanev](https://github.com/shanev)) +- add query\_this\_hook to hooks.rs [\#688](https://github.com/CosmWasm/cw-plus/pull/688) ([ishaanh](https://github.com/ishaanh)) ## [v0.13.4](https://github.com/CosmWasm/cw-plus/tree/v0.13.4) (2022-06-02) From bc133231063aaa5ae779d2af1b48cc2a4325d979 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 27 Jul 2022 12:30:21 +0200 Subject: [PATCH 394/631] Add optimizer.sh script --- scripts/optimizer.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 scripts/optimizer.sh diff --git a/scripts/optimizer.sh b/scripts/optimizer.sh new file mode 100755 index 000000000..7bc022aef --- /dev/null +++ b/scripts/optimizer.sh @@ -0,0 +1,16 @@ +: + +U="cosmwasm" +V="0.12.6" + +M=$(uname -m) +#M="x86_64" # Force Intel arch + +A="linux/${M/x86_64/amd64}" +S=${M#x86_64} +S=${S:+-$S} + +docker run --platform $A --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + $U/workspace-optimizer$S:$V From f021bcef12a1490e71c3231f2b9f4eb2255713a2 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 28 Jul 2022 13:59:44 +0200 Subject: [PATCH 395/631] Fix publish.sh syntax --- scripts/publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 783c3b3b0..488cf79bc 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -7,7 +7,7 @@ function print_usage() { echo "Publishes crates to crates.io." } -if [ $# = 1 ] && ( [ "$1" = "-h" ] || [ "$1" = "--help" ] ) +if [ $# = 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ] ; } then print_usage exit 1 From 7638d798713a36a24e5b42b0700fdc4d7fbc9b23 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 28 Jul 2022 14:00:05 +0200 Subject: [PATCH 396/631] Workaround for breaking storage-macro/plus cyclic deps --- packages/storage-macro/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index a4389f414..76e81f45e 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -16,6 +16,6 @@ proc-macro = true syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] -cw-storage-plus = { version = "0.14.0", path = "../storage-plus" } +cw-storage-plus = { version = "<=0.14.0, >=0.13.4", path = "../storage-plus" } cosmwasm-std = { version = "1.0.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } From e3a6d294be08945bdb7c48c263446f0716662c40 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 28 Jul 2022 14:03:08 +0200 Subject: [PATCH 397/631] Add storage-macro to publish script --- scripts/publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 488cf79bc..96c1cb3a6 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -14,7 +14,7 @@ then fi # this should really more to cosmwasm... -STORAGE_PACKAGES="storage-plus" +STORAGE_PACKAGES="storage-macro storage-plus" # these are imported by other packages BASE_PACKAGES="utils" ALL_PACKAGES="controllers cw1 cw2 cw3 cw4 cw20 cw1155 multi-test" From c86b1c02cd2a9cb1b726d6968cd40b0ad6a40d2c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 28 Jul 2022 15:19:09 +0200 Subject: [PATCH 398/631] Change / fix packages publishing order --- scripts/publish.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 96c1cb3a6..27028ac21 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -16,8 +16,9 @@ fi # this should really more to cosmwasm... STORAGE_PACKAGES="storage-macro storage-plus" # these are imported by other packages -BASE_PACKAGES="utils" -ALL_PACKAGES="controllers cw1 cw2 cw3 cw4 cw20 cw1155 multi-test" +BASE_PACKAGES="cw2" +UTILS_PACKAGES="utils" +ALL_PACKAGES="controllers cw1 cw3 cw4 cw20 cw1155 multi-test" # This is imported by cw3-fixed-multisig, which is imported by cw3-flex-multisig # need to make a separate category to remove race conditions @@ -52,6 +53,18 @@ done echo "Waiting for publishing base packages" sleep $SLEEP_TIME +for pack in $UTILS_PACKAGES; do + ( + cd "packages/$pack" + echo "Publishing $pack" + cargo publish + ) +done + +# wait for these to be processed on crates.io +echo "Waiting for publishing utils packages" +sleep $SLEEP_TIME + for pack in $ALL_PACKAGES; do ( cd "packages/$pack" From 39c5a8a793a33b5534ea32764cbab6a8306934c3 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 2 Aug 2022 00:55:41 -0500 Subject: [PATCH 399/631] Update contract.rs Made ExecuteEnv fields public to allow methods to be imported. --- contracts/cw1155-base/src/contract.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 8150809f1..5add6b405 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -39,9 +39,9 @@ pub fn instantiate( /// To mitigate clippy::too_many_arguments warning pub struct ExecuteEnv<'a> { - deps: DepsMut<'a>, - env: Env, - info: MessageInfo, + pub deps: DepsMut<'a>, + pub env: Env, + pub info: MessageInfo, } #[cfg_attr(not(feature = "library"), entry_point)] From c8374aa0604648dad99ea63aaba35c8af23386ad Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 8 Aug 2022 12:40:39 +0800 Subject: [PATCH 400/631] feat: expose failing module --- packages/multi-test/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index b532a8152..eaae75c4d 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -26,6 +26,6 @@ pub use crate::app::{ pub use crate::bank::{Bank, BankKeeper, BankSudo}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; -pub use crate::module::Module; +pub use crate::module::{Module, FailingModule}; pub use crate::staking::{FailingDistribution, FailingStaking, Staking, StakingSudo}; pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; From 753fbe1bda0d3894474c7b4aa4afca0abe969d0e Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 8 Aug 2022 14:09:37 +0800 Subject: [PATCH 401/631] chore: run cargo fmt --- packages/multi-test/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index eaae75c4d..29ad0846e 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -26,6 +26,6 @@ pub use crate::app::{ pub use crate::bank::{Bank, BankKeeper, BankSudo}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; -pub use crate::module::{Module, FailingModule}; +pub use crate::module::{FailingModule, Module}; pub use crate::staking::{FailingDistribution, FailingStaking, Staking, StakingSudo}; pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; From db7db1bf9d8a3d2b08bca6aa551b075d6618736c Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 8 Aug 2022 11:29:36 +0200 Subject: [PATCH 402/631] Fix: Prefix::keys doesn't eat errors anymore --- packages/storage-plus/src/prefix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs index 260baf0e7..6922226e8 100644 --- a/packages/storage-plus/src/prefix.rs +++ b/packages/storage-plus/src/prefix.rs @@ -185,7 +185,7 @@ where max.map(|b| b.to_raw_bound()), order, ) - .flat_map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| Ok(k))); + .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| k)); Box::new(mapped) } } From 77cd091678b2b907df8a219a9778b77978254ffe Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 8 Aug 2022 14:47:58 +0200 Subject: [PATCH 403/631] Add broken deserialization errors checks for range and keys --- packages/storage-plus/src/map.rs | 104 +++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index eee46f5c1..75ad389be 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -267,6 +267,8 @@ mod test { use std::ops::Deref; use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::to_binary; + use cosmwasm_std::StdError::InvalidUtf8; #[cfg(feature = "iterator")] use cosmwasm_std::{Order, StdResult}; @@ -285,6 +287,10 @@ mod test { const PEOPLE: Map<&[u8], Data> = Map::new("people"); #[cfg(feature = "iterator")] + const PEOPLE_STR_KEY: &str = "people2"; + #[cfg(feature = "iterator")] + const PEOPLE_STR: Map<&str, Data> = Map::new(PEOPLE_STR_KEY); + #[cfg(feature = "iterator")] const PEOPLE_ID: Map = Map::new("people_id"); #[cfg(feature = "iterator")] const SIGNED_ID_OLD: Map, Data> = Map::new("signed_id"); @@ -539,6 +545,104 @@ mod test { assert_eq!(all, vec![(b"john".to_vec(), data)]); } + #[test] + #[cfg(feature = "iterator")] + fn range_key_broken_deserialization_errors() { + let mut store = MockStorage::new(); + + // save and load on three keys + let data = Data { + name: "John".to_string(), + age: 32, + }; + PEOPLE_STR.save(&mut store, "john", &data).unwrap(); + + let data2 = Data { + name: "Jim".to_string(), + age: 44, + }; + PEOPLE_STR.save(&mut store, "jim", &data2).unwrap(); + + let data3 = Data { + name: "Ada".to_string(), + age: 23, + }; + PEOPLE_STR.save(&mut store, "ada", &data3).unwrap(); + + // let's iterate! + let all: StdResult> = PEOPLE_STR + .range(&store, None, None, Order::Ascending) + .collect(); + let all = all.unwrap(); + assert_eq!(3, all.len()); + assert_eq!( + all, + vec![ + ("ada".to_string(), data3.clone()), + ("jim".to_string(), data2.clone()), + ("john".to_string(), data.clone()) + ] + ); + + // Manually add a broken key (invalid utf-8) + store.set( + &*[ + [0u8, PEOPLE_STR_KEY.len() as u8].as_slice(), + PEOPLE_STR_KEY.as_bytes(), + b"\xddim", + ] + .concat(), + &to_binary(&data2).unwrap(), + ); + + // Let's try to iterate again! + let all: StdResult> = PEOPLE_STR + .range(&store, None, None, Order::Ascending) + .collect(); + assert!(all.is_err()); + assert!(matches!(all.unwrap_err(), InvalidUtf8 { .. })); + + // And the same with keys() + let all: StdResult> = PEOPLE_STR + .keys(&store, None, None, Order::Ascending) + .collect(); + assert!(all.is_err()); + assert!(matches!(all.unwrap_err(), InvalidUtf8 { .. })); + + // But range_raw still works + let all: StdResult> = PEOPLE_STR + .range_raw(&store, None, None, Order::Ascending) + .collect(); + + let all = all.unwrap(); + assert_eq!(4, all.len()); + assert_eq!( + all, + vec![ + (b"ada".to_vec(), data3.clone()), + (b"jim".to_vec(), data2.clone()), + (b"john".to_vec(), data.clone()), + (b"\xddim".to_vec(), data2.clone()), + ] + ); + + // And the same with keys_raw + let all: Vec<_> = PEOPLE_STR + .keys_raw(&store, None, None, Order::Ascending) + .collect(); + + assert_eq!(4, all.len()); + assert_eq!( + all, + vec![ + b"ada".to_vec(), + b"jim".to_vec(), + b"john".to_vec(), + b"\xddim".to_vec(), + ] + ); + } + #[test] #[cfg(feature = "iterator")] fn range_simple_integer_key() { From b6195d0a8ce65f45456744408968e3d31fbc5a8a Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 9 Aug 2022 13:47:41 +0200 Subject: [PATCH 404/631] Small fixes / updates to storage-plus docs --- packages/storage-plus/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 3e2691df1..f06776146 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -28,7 +28,7 @@ on top of `cosmwasm_std::Storage`. They are `Item`, which is a typed wrapper around one database key, providing some helper functions for interacting with it without dealing with raw bytes. And `Map`, which allows you to store multiple unique typed objects under a prefix, -indexed by a simple (`&[u8]`) or compound (eg. `(&[u8], &[u8])`) primary key. +indexed by a simple or compound (eg. `(&[u8], &[u8])`) primary key. These correspond to the concepts represented in `cosmwasm_storage` by `Singleton` and `Bucket`, but with a re-designed API and implementation @@ -111,9 +111,9 @@ fn demo() -> StdResult<()> { The usage of a [`Map`](./src/map.rs) is a little more complex, but is still pretty straight-forward. You can imagine it as a storage-backed `BTreeMap`, allowing key-value lookups with typed values. In addition, -we support not only simple binary keys (`&[u8]`), but tuples, which are -combined. This allows us to store allowances as composite keys -eg. `(owner, spender)` to look up the balance. +we support not only simple binary keys (like `&[u8]`), but tuples, which are +combined. This allows us by example to store allowances as composite keys, +i.e. `(owner, spender)` to look up the balance. Beyond direct lookups, we have a super-power not found in Ethereum - iteration. That's right, you can list all items in a `Map`, or only @@ -209,8 +209,8 @@ A `Map` key can be anything that implements the `PrimaryKey` trait. There are a - `impl<'a> PrimaryKey<'a> for &'a Addr` - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a>> PrimaryKey<'a> for (T, U)` - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a> + Prefixer<'a>, V: PrimaryKey<'a>> PrimaryKey<'a> for (T, U, V)` - - `PrimaryKey` implemented for unsigned integers up to `u64` - - `PrimaryKey` implemented for signed integers up to `i64` + - `PrimaryKey` implemented for unsigned integers up to `u128` + - `PrimaryKey` implemented for signed integers up to `i128` That means that byte and string slices, byte vectors, and strings, can be conveniently used as keys. Moreover, some other types can be used as well, like addresses and address references, pairs, triples, and @@ -236,7 +236,7 @@ one owner" (first part of the composite key). Just like you'd expect from your favorite database. Here's how we use it with composite keys. Just define a tuple as a key and use that -everywhere you used a byte slice above. +everywhere you used a single key above. ```rust // Note the tuple for primary key. We support one slice, or a 2 or 3-tuple. @@ -271,13 +271,13 @@ fn demo() -> StdResult<()> { ### Path Under the scenes, we create a `Path` from the `Map` when accessing a key. -`PEOPLE.load(&store, b"jack") == PEOPLE.key(b"jack").load()`. +`PEOPLE.load(&store, "jack") == PEOPLE.key("jack").load()`. `Map.key()` returns a `Path`, which has the same interface as `Item`, re-using the calculated path to this key. For simple keys, this is just a bit less typing and a bit less gas if you use the same key for many calls. However, for composite keys, like -`(b"owner", b"spender")` it is **much** less typing. And highly recommended anywhere +`("owner", "spender")` it is **much** less typing. And highly recommended anywhere you will use a composite key even twice: ```rust From 15452cacea79aef1c8c706eaff5fd5caceae910e Mon Sep 17 00:00:00 2001 From: Etienne Napoleone Date: Sun, 7 Aug 2022 18:16:57 +0200 Subject: [PATCH 405/631] Style: move `InstantiateMsg` validation in impl --- contracts/cw20-base/src/msg.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index e2d4239d5..d7c22db28 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -30,12 +30,12 @@ impl InstantiateMsg { pub fn validate(&self) -> StdResult<()> { // Check name, symbol, decimals - if !is_valid_name(&self.name) { + if !self.has_valid_name() { return Err(StdError::generic_err( "Name is not in the expected format (3-50 UTF-8 bytes)", )); } - if !is_valid_symbol(&self.symbol) { + if !self.has_valid_symbol() { return Err(StdError::generic_err( "Ticker symbol is not in expected format [a-zA-Z\\-]{3,12}", )); @@ -45,27 +45,27 @@ impl InstantiateMsg { } Ok(()) } -} -fn is_valid_name(name: &str) -> bool { - let bytes = name.as_bytes(); - if bytes.len() < 3 || bytes.len() > 50 { - return false; + fn has_valid_name(&self) -> bool { + let bytes = self.name.as_bytes(); + if bytes.len() < 3 || bytes.len() > 50 { + return false; + } + true } - true -} -fn is_valid_symbol(symbol: &str) -> bool { - let bytes = symbol.as_bytes(); - if bytes.len() < 3 || bytes.len() > 12 { - return false; - } - for byte in bytes.iter() { - if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) { + fn has_valid_symbol(&self) -> bool { + let bytes = self.symbol.as_bytes(); + if bytes.len() < 3 || bytes.len() > 12 { return false; } + for byte in bytes.iter() { + if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) { + return false; + } + } + true } - true } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] From 7a0aff8696bd1fb074bf33ab073a8f998145d347 Mon Sep 17 00:00:00 2001 From: etienne-napoleone Date: Wed, 10 Aug 2022 15:34:36 +0200 Subject: [PATCH 406/631] Add tests to cw20 `InstantiateMsg` --- contracts/cw20-base/src/msg.rs | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index d7c22db28..27f3a5b52 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -14,6 +14,7 @@ pub struct InstantiateMarketingInfo { } #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[cfg_attr(test, derive(Default))] pub struct InstantiateMsg { pub name: String, pub symbol: String, @@ -122,3 +123,52 @@ pub enum QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] pub struct MigrateMsg {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn validate_instantiatemsg_name() { + // Too short + let mut msg = InstantiateMsg { + name: str::repeat("a", 2), + ..InstantiateMsg::default() + }; + assert!(!msg.has_valid_name()); + + // In the correct length range + msg.name = str::repeat("a", 3); + assert!(msg.has_valid_name()); + + // Too long + msg.name = str::repeat("a", 51); + assert!(!msg.has_valid_name()); + } + + #[test] + fn validate_instantiatemsg_symbol() { + // Too short + let mut msg = InstantiateMsg { + symbol: str::repeat("a", 2), + ..InstantiateMsg::default() + }; + assert!(!msg.has_valid_symbol()); + + // In the correct length range + msg.symbol = str::repeat("a", 3); + assert!(msg.has_valid_symbol()); + + // Too long + msg.symbol = str::repeat("a", 13); + assert!(!msg.has_valid_symbol()); + + // Has illegal char + let illegal_chars = [[64u8], [91u8], [123u8]]; + illegal_chars.iter().for_each(|c| { + let c = std::str::from_utf8(c).unwrap(); + msg.symbol = str::repeat(c, 3); + assert!(!msg.has_valid_symbol()); + }); + } +} From b0faaa53b24b5cd81f3dd6cb1af203631cf9fe68 Mon Sep 17 00:00:00 2001 From: LeTurt <89463679+LeTurt333@users.noreply.github.com> Date: Sun, 14 Aug 2022 03:19:42 -0700 Subject: [PATCH 407/631] Fix small typo Fix a small typo in the Composite Key example of the Bound section --- packages/storage-plus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index f06776146..a47823688 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -417,7 +417,7 @@ fn demo() -> StdResult<()> { .prefix("owner") .range( &store, - Some(Bound::exclusive("spender1")), + Some(Bound::exclusive("spender")), Some(Bound::inclusive("spender2")), Order::Descending, ) From 972b6934c147007856c66026373f84e8eae81a1a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 20 Jul 2022 17:29:53 +0200 Subject: [PATCH 408/631] contracts: move schema gen boilerplate to a binary crate --- contracts/cw1-subkeys/.cargo/config | 2 +- contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-subkeys/{examples => src/bin}/schema.rs | 0 contracts/cw1-whitelist-ng/.cargo/config | 2 +- contracts/cw1-whitelist-ng/Cargo.toml | 2 +- contracts/cw1-whitelist-ng/{examples => src/bin}/schema.rs | 0 contracts/cw1-whitelist/.cargo/config | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- contracts/cw1-whitelist/{examples => src/bin}/schema.rs | 0 contracts/cw1155-base/.cargo/config | 2 +- contracts/cw1155-base/Cargo.toml | 4 +--- contracts/cw1155-base/{examples => src/bin}/schema.rs | 0 contracts/cw20-base/.cargo/config | 2 +- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-base/{examples => src/bin}/schema.rs | 0 contracts/cw20-ics20/.cargo/config | 2 +- contracts/cw20-ics20/Cargo.toml | 4 +--- contracts/cw20-ics20/{examples => src/bin}/schema.rs | 0 contracts/cw3-fixed-multisig/.cargo/config | 2 +- contracts/cw3-fixed-multisig/Cargo.toml | 2 +- contracts/cw3-fixed-multisig/{examples => src/bin}/schema.rs | 0 contracts/cw3-flex-multisig/.cargo/config | 2 +- contracts/cw3-flex-multisig/Cargo.toml | 2 +- contracts/cw3-flex-multisig/{examples => src/bin}/schema.rs | 0 contracts/cw4-group/.cargo/config | 2 +- contracts/cw4-group/Cargo.toml | 4 +--- contracts/cw4-group/{examples => src/bin}/schema.rs | 0 contracts/cw4-stake/.cargo/config | 2 +- contracts/cw4-stake/Cargo.toml | 4 +--- contracts/cw4-stake/{examples => src/bin}/schema.rs | 0 30 files changed, 20 insertions(+), 28 deletions(-) rename contracts/cw1-subkeys/{examples => src/bin}/schema.rs (100%) rename contracts/cw1-whitelist-ng/{examples => src/bin}/schema.rs (100%) rename contracts/cw1-whitelist/{examples => src/bin}/schema.rs (100%) rename contracts/cw1155-base/{examples => src/bin}/schema.rs (100%) rename contracts/cw20-base/{examples => src/bin}/schema.rs (100%) rename contracts/cw20-ics20/{examples => src/bin}/schema.rs (100%) rename contracts/cw3-fixed-multisig/{examples => src/bin}/schema.rs (100%) rename contracts/cw3-flex-multisig/{examples => src/bin}/schema.rs (100%) rename contracts/cw4-group/{examples => src/bin}/schema.rs (100%) rename contracts/cw4-stake/{examples => src/bin}/schema.rs (100%) diff --git a/contracts/cw1-subkeys/.cargo/config b/contracts/cw1-subkeys/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw1-subkeys/.cargo/config +++ b/contracts/cw1-subkeys/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 8e79436f3..3db259ffa 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,6 +19,7 @@ library = [] test-utils = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } @@ -31,5 +32,4 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-subkeys/examples/schema.rs b/contracts/cw1-subkeys/src/bin/schema.rs similarity index 100% rename from contracts/cw1-subkeys/examples/schema.rs rename to contracts/cw1-subkeys/src/bin/schema.rs diff --git a/contracts/cw1-whitelist-ng/.cargo/config b/contracts/cw1-whitelist-ng/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw1-whitelist-ng/.cargo/config +++ b/contracts/cw1-whitelist-ng/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index eacafb300..7ca6293cf 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -22,6 +22,7 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } @@ -36,6 +37,5 @@ anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } derivative = "2" diff --git a/contracts/cw1-whitelist-ng/examples/schema.rs b/contracts/cw1-whitelist-ng/src/bin/schema.rs similarity index 100% rename from contracts/cw1-whitelist-ng/examples/schema.rs rename to contracts/cw1-whitelist-ng/src/bin/schema.rs diff --git a/contracts/cw1-whitelist/.cargo/config b/contracts/cw1-whitelist/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw1-whitelist/.cargo/config +++ b/contracts/cw1-whitelist/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index f9e011fc7..e64a7751c 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,6 +19,7 @@ library = [] test-utils = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } @@ -31,6 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/examples/schema.rs b/contracts/cw1-whitelist/src/bin/schema.rs similarity index 100% rename from contracts/cw1-whitelist/examples/schema.rs rename to contracts/cw1-whitelist/src/bin/schema.rs diff --git a/contracts/cw1155-base/.cargo/config b/contracts/cw1155-base/.cargo/config index 7d1a066c8..08d13a665 100644 --- a/contracts/cw1155-base/.cargo/config +++ b/contracts/cw1155-base/.cargo/config @@ -2,4 +2,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index d95ed6fd8..44b19e703 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -18,6 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw1155 = { path = "../../packages/cw1155", version = "0.14.0" } @@ -26,6 +27,3 @@ cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw1155-base/examples/schema.rs b/contracts/cw1155-base/src/bin/schema.rs similarity index 100% rename from contracts/cw1155-base/examples/schema.rs rename to contracts/cw1155-base/src/bin/schema.rs diff --git a/contracts/cw20-base/.cargo/config b/contracts/cw20-base/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw20-base/.cargo/config +++ b/contracts/cw20-base/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index d5a2b5c67..ee071fd12 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -18,6 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } @@ -29,5 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw20-base/examples/schema.rs b/contracts/cw20-base/src/bin/schema.rs similarity index 100% rename from contracts/cw20-base/examples/schema.rs rename to contracts/cw20-base/src/bin/schema.rs diff --git a/contracts/cw20-ics20/.cargo/config b/contracts/cw20-ics20/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw20-ics20/.cargo/config +++ b/contracts/cw20-ics20/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 51f960bb9..a143085fa 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -18,6 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } @@ -28,6 +29,3 @@ schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw20-ics20/examples/schema.rs b/contracts/cw20-ics20/src/bin/schema.rs similarity index 100% rename from contracts/cw20-ics20/examples/schema.rs rename to contracts/cw20-ics20/src/bin/schema.rs diff --git a/contracts/cw3-fixed-multisig/.cargo/config b/contracts/cw3-fixed-multisig/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw3-fixed-multisig/.cargo/config +++ b/contracts/cw3-fixed-multisig/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 5986fde00..6c0a6928a 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -18,6 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } @@ -28,7 +29,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } cw20-base = { path = "../cw20-base", version = "0.14.0", features = ["library"] } cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw3-fixed-multisig/examples/schema.rs b/contracts/cw3-fixed-multisig/src/bin/schema.rs similarity index 100% rename from contracts/cw3-fixed-multisig/examples/schema.rs rename to contracts/cw3-fixed-multisig/src/bin/schema.rs diff --git a/contracts/cw3-flex-multisig/.cargo/config b/contracts/cw3-flex-multisig/.cargo/config index 8d4bc738b..4e0626844 100644 --- a/contracts/cw3-flex-multisig/.cargo/config +++ b/contracts/cw3-flex-multisig/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index aded312db..2db50dd24 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -18,6 +18,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } @@ -30,6 +31,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } cw4-group = { path = "../cw4-group", version = "0.14.0" } cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } diff --git a/contracts/cw3-flex-multisig/examples/schema.rs b/contracts/cw3-flex-multisig/src/bin/schema.rs similarity index 100% rename from contracts/cw3-flex-multisig/examples/schema.rs rename to contracts/cw3-flex-multisig/src/bin/schema.rs diff --git a/contracts/cw4-group/.cargo/config b/contracts/cw4-group/.cargo/config index 7d1a066c8..08d13a665 100644 --- a/contracts/cw4-group/.cargo/config +++ b/contracts/cw4-group/.cargo/config @@ -2,4 +2,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 3505be4b1..125e23477 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -26,6 +26,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } @@ -35,6 +36,3 @@ cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw4-group/examples/schema.rs b/contracts/cw4-group/src/bin/schema.rs similarity index 100% rename from contracts/cw4-group/examples/schema.rs rename to contracts/cw4-group/src/bin/schema.rs diff --git a/contracts/cw4-stake/.cargo/config b/contracts/cw4-stake/.cargo/config index 7d1a066c8..08d13a665 100644 --- a/contracts/cw4-stake/.cargo/config +++ b/contracts/cw4-stake/.cargo/config @@ -2,4 +2,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 3c330837a..188d9cda6 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -26,6 +26,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] +cosmwasm-schema = { version = "1.0.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } @@ -36,6 +37,3 @@ cosmwasm-std = { version = "1.0.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } diff --git a/contracts/cw4-stake/examples/schema.rs b/contracts/cw4-stake/src/bin/schema.rs similarity index 100% rename from contracts/cw4-stake/examples/schema.rs rename to contracts/cw4-stake/src/bin/schema.rs From f850218312aadef513f721585c08e1771508c091 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 12 Aug 2022 09:08:21 +0200 Subject: [PATCH 409/631] storage-plus: Remove IntKeyOld and associated structures --- packages/storage-plus/src/de_old.rs | 106 -------------------------- packages/storage-plus/src/keys_old.rs | 105 ------------------------- packages/storage-plus/src/lib.rs | 3 - packages/storage-plus/src/map.rs | 74 ------------------ 4 files changed, 288 deletions(-) delete mode 100644 packages/storage-plus/src/de_old.rs delete mode 100644 packages/storage-plus/src/keys_old.rs diff --git a/packages/storage-plus/src/de_old.rs b/packages/storage-plus/src/de_old.rs deleted file mode 100644 index e8c5f529d..000000000 --- a/packages/storage-plus/src/de_old.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::array::TryFromSliceError; -use std::convert::TryInto; - -use cosmwasm_std::{StdError, StdResult}; - -use crate::de::KeyDeserialize; -use crate::keys_old::IntKeyOld; - -macro_rules! intkey_old_de { - (for $($t:ty),+) => { - $(impl KeyDeserialize for IntKeyOld<$t> { - type Output = $t; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(<$t>::from_be_bytes(value.as_slice().try_into() - .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) - } - })* - } -} - -intkey_old_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); - -#[cfg(test)] -mod test { - use super::*; - use crate::keys_old::IntKeyOld; - - #[test] - fn deserialize_integer_old_works() { - assert_eq!(>::from_slice(&[1]).unwrap(), 1u8); - assert_eq!(>::from_slice(&[127]).unwrap(), 127i8); - assert_eq!(>::from_slice(&[128]).unwrap(), -128i8); - - assert_eq!(>::from_slice(&[1, 0]).unwrap(), 256u16); - assert_eq!(>::from_slice(&[128, 0]).unwrap(), -32768i16); - assert_eq!(>::from_slice(&[127, 255]).unwrap(), 32767i16); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0]).unwrap(), - 16777216u32 - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0]).unwrap(), - -2147483648i32 - ); - assert_eq!( - >::from_slice(&[127, 255, 255, 255]).unwrap(), - 2147483647i32 - ); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 72057594037927936u64 - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - -9223372036854775808i64 - ); - assert_eq!( - >::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), - 9223372036854775807i64 - ); - - assert_eq!( - >::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - .unwrap(), - 1329227995784915872903807060280344576u128 - ); - assert_eq!( - >::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - .unwrap(), - -170141183460469231731687303715884105728i128 - ); - assert_eq!( - >::from_slice(&[ - 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - 170141183460469231731687303715884105727i128 - ); - assert_eq!( - >::from_slice(&[ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - -1i128, - ); - } - - #[test] - fn deserialize_broken_integer_old_errs() { - // One byte less fails - assert!(matches!( - >::from_slice(&[1]).err(), - Some(StdError::GenericErr { .. }) - )); - - // More bytes fails too - assert!(matches!( - >::from_slice(&[1, 2]).err(), - Some(StdError::GenericErr { .. }) - )); - } -} diff --git a/packages/storage-plus/src/keys_old.rs b/packages/storage-plus/src/keys_old.rs deleted file mode 100644 index 97752ae03..000000000 --- a/packages/storage-plus/src/keys_old.rs +++ /dev/null @@ -1,105 +0,0 @@ -use crate::de::KeyDeserialize; -use crate::keys::Key; -#[cfg(feature = "iterator")] -use crate::{Bound, Bounder}; -use crate::{Endian, Prefixer, PrimaryKey}; -use std::marker::PhantomData; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct IntKeyOld { - pub wrapped: Vec, - pub data: PhantomData, -} - -impl IntKeyOld { - pub fn new(val: T) -> Self { - IntKeyOld { - wrapped: val.to_be_bytes().into(), - data: PhantomData, - } - } -} - -impl From for IntKeyOld { - fn from(val: T) -> Self { - IntKeyOld::new(val) - } -} - -impl From> for IntKeyOld { - fn from(wrap: Vec) -> Self { - IntKeyOld { - wrapped: wrap, - data: PhantomData, - } - } -} - -impl From> for Vec { - fn from(k: IntKeyOld) -> Vec { - k.wrapped - } -} - -// this auto-implements PrimaryKey for all the IntKeyOld types -impl<'a, T: Endian + Clone> PrimaryKey<'a> for IntKeyOld -where - IntKeyOld: KeyDeserialize, -{ - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - self.wrapped.key() - } -} - -// this auto-implements Prefixer for all the IntKey types -impl<'a, T: Endian> Prefixer<'a> for IntKeyOld { - fn prefix(&self) -> Vec { - self.wrapped.prefix() - } -} - -// this auto-implements Bounder for all the IntKey types -#[cfg(feature = "iterator")] -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::*; - - #[test] - fn u64key_old_works() { - let k: IntKeyOld = 134u64.into(); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(134u64.to_be_bytes(), path[0].as_ref()); - } - - #[test] - fn i32key_old_works() { - let k: IntKeyOld = 4242i32.into(); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242i32.to_be_bytes(), path[0].as_ref()); - - let k: IntKeyOld = IntKeyOld::::from(-4242i32); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!((-4242i32).to_be_bytes(), path[0].as_ref()); - } -} diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index d6f93efb3..4aa9c6567 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -1,6 +1,5 @@ mod bound; mod de; -mod de_old; mod endian; mod helpers; mod indexed_map; @@ -10,7 +9,6 @@ mod int_key; mod item; mod iter_helpers; mod keys; -mod keys_old; mod map; mod path; mod prefix; @@ -33,7 +31,6 @@ pub use indexes::UniqueIndex; pub use int_key::CwIntKey; pub use item::Item; pub use keys::{Key, Prefixer, PrimaryKey}; -pub use keys_old::IntKeyOld; pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 75ad389be..f2fc4e05a 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -276,8 +276,6 @@ mod test { use crate::bound::Bounder; use crate::int_key::CwIntKey; - #[cfg(feature = "iterator")] - use crate::IntKeyOld; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { @@ -293,8 +291,6 @@ mod test { #[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: Map = Map::new("signed_id"); const ALLOWANCE: Map<(&[u8], &[u8]), u64> = Map::new("allow"); @@ -860,76 +856,6 @@ mod test { assert_eq!(all, vec![(50, data3)]); } - #[test] - #[cfg(feature = "iterator")] - fn range_signed_integer_key_migration() { - let mut store = MockStorage::new(); - - // save and load three keys with the old format - let data = Data { - name: "John".to_string(), - age: 32, - }; - SIGNED_ID_OLD - .save(&mut store, IntKeyOld::::from(-1234), &data) - .unwrap(); - - let data2 = Data { - name: "Jim".to_string(), - age: 44, - }; - SIGNED_ID_OLD - .save(&mut store, IntKeyOld::::from(-56), &data2) - .unwrap(); - - let data3 = Data { - name: "Jules".to_string(), - age: 55, - }; - SIGNED_ID_OLD - .save(&mut store, IntKeyOld::::from(50), &data3) - .unwrap(); - - // obtain all current keys - let current = SIGNED_ID_OLD - .range(&store, None, None, Order::Ascending) - .collect::>>() - .unwrap(); - // confirm wrong current order - assert_eq!( - current, - vec![ - (50, data3.clone()), - (-1234, data.clone()), - (-56, data2.clone()) - ] - ); - - // remove old entries - for (k, _) in current.iter() { - SIGNED_ID_OLD.remove(&mut store, (*k).into()); - } - - // confirm map is empty - assert!(SIGNED_ID_OLD - .range(&store, None, None, Order::Ascending) - .next() - .is_none()); - - // save in new format - for (k, v) in current.into_iter() { - SIGNED_ID.save(&mut store, k, &v).unwrap(); - } - - // obtain new keys - let new = SIGNED_ID - .range(&store, None, None, Order::Ascending) - .collect::>>() - .unwrap(); - // confirm new order is right - assert_eq!(new, vec![(-1234, data), (-56, data2), (50, data3)]); - } - #[test] #[cfg(feature = "iterator")] fn range_raw_composite_key() { From 23136bba916bb129229d132e7911d848791425fe Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 12 Aug 2022 12:55:23 +0200 Subject: [PATCH 410/631] storage-plus: Rename CwIntKey trait to IntKey --- packages/storage-plus/benches/main.rs | 2 +- packages/storage-plus/src/de.rs | 2 +- packages/storage-plus/src/int_key.rs | 7 +++---- packages/storage-plus/src/keys.rs | 2 +- packages/storage-plus/src/lib.rs | 2 +- packages/storage-plus/src/map.rs | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs index 1b5e557b1..a0623257f 100644 --- a/packages/storage-plus/benches/main.rs +++ b/packages/storage-plus/benches/main.rs @@ -4,7 +4,7 @@ use rand::Rng; use std::mem; use std::time::Duration; -use cw_storage_plus::CwIntKey; +use cw_storage_plus::IntKey; fn bench_signed_int_key(c: &mut Criterion) { let mut group = c.benchmark_group("Signed int keys"); diff --git a/packages/storage-plus/src/de.rs b/packages/storage-plus/src/de.rs index c1b13889f..046d8b9cb 100644 --- a/packages/storage-plus/src/de.rs +++ b/packages/storage-plus/src/de.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use cosmwasm_std::{Addr, StdError, StdResult}; -use crate::int_key::CwIntKey; +use crate::int_key::IntKey; pub trait KeyDeserialize { type Output: Sized; diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs index 7f7713369..0292674a2 100644 --- a/packages/storage-plus/src/int_key.rs +++ b/packages/storage-plus/src/int_key.rs @@ -4,8 +4,7 @@ use std::mem; /// but "sign-flipped" (xored msb) big-endian bytes for signed ints. /// /// So that the representation of signed integers is in the right lexicographical order. -// TODO: Rename to `IntKey` after deprecating current `IntKey` (https://github.com/CosmWasm/cw-plus/issues/570) -pub trait CwIntKey: Sized + Copy { +pub trait IntKey: Sized + Copy { type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; fn to_cw_bytes(&self) -> Self::Buf; @@ -14,7 +13,7 @@ pub trait CwIntKey: Sized + Copy { macro_rules! cw_uint_keys { (for $($t:ty),+) => { - $(impl CwIntKey for $t { + $(impl IntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] @@ -34,7 +33,7 @@ cw_uint_keys!(for u8, u16, u32, u64, u128); macro_rules! cw_int_keys { (for $($t:ty, $ut:ty),+) => { - $(impl CwIntKey for $t { + $(impl IntKey for $t { type Buf = [u8; mem::size_of::<$t>()]; #[inline] diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs index 9e55bfd5b..cf7eff867 100644 --- a/packages/storage-plus/src/keys.rs +++ b/packages/storage-plus/src/keys.rs @@ -2,7 +2,7 @@ use cosmwasm_std::Addr; use crate::de::KeyDeserialize; use crate::helpers::namespaces_with_key; -use crate::int_key::CwIntKey; +use crate::int_key::IntKey; #[derive(Debug)] pub enum Key<'a> { diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 4aa9c6567..03b2b52d1 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -28,7 +28,7 @@ pub use indexes::Index; pub use indexes::MultiIndex; #[cfg(feature = "iterator")] pub use indexes::UniqueIndex; -pub use int_key::CwIntKey; +pub use int_key::IntKey; pub use item::Item; pub use keys::{Key, Prefixer, PrimaryKey}; pub use map::Map; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index f2fc4e05a..67d243af0 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -275,7 +275,7 @@ mod test { #[cfg(feature = "iterator")] use crate::bound::Bounder; - use crate::int_key::CwIntKey; + use crate::int_key::IntKey; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Data { From fd6543d1ea58ba0bacb7f4d76aef0de9cc1f328f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 16 Aug 2022 21:58:01 +0200 Subject: [PATCH 411/631] Add (raw) primary key to MultiIndex index fn params --- packages/storage-plus/src/indexes/multi.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs index f3a4bd70a..b40ee202e 100644 --- a/packages/storage-plus/src/indexes/multi.rs +++ b/packages/storage-plus/src/indexes/multi.rs @@ -24,11 +24,11 @@ use std::marker::PhantomData; /// the secondary load of the associated value from the main map. /// /// The PK type defines the type of Primary Key, both for deserialization, and -/// more important, type-safe bound key type. +/// more important, as the type-safe bound key type. /// This type must match the encompassing `IndexedMap` primary key type, /// or its owned variant. pub struct MultiIndex<'a, IK, T, PK> { - index: fn(&T) -> IK, + index: fn(&[u8], &T) -> IK, idx_namespace: &'a [u8], // note, we collapse the ik - combining everything under the namespace - and concatenating the pk idx_map: Map<'a, Vec, u32>, @@ -60,12 +60,12 @@ where /// } /// /// let index: MultiIndex<_, _, String> = MultiIndex::new( - /// |d: &Data| d.age, + /// |_pk: &[u8], d: &Data| d.age, /// "age", /// "age__owner", /// ); /// ``` - pub fn new(idx_fn: fn(&T) -> IK, pk_namespace: &'a str, idx_namespace: &'a str) -> Self { + pub fn new(idx_fn: fn(&[u8], &T) -> IK, pk_namespace: &'a str, idx_namespace: &'a str) -> Self { MultiIndex { index: idx_fn, idx_namespace: idx_namespace.as_bytes(), @@ -131,12 +131,12 @@ where IK: PrimaryKey<'a>, { fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()> { - let idx = (self.index)(data).joined_extra_key(pk); + let idx = (self.index)(pk, data).joined_extra_key(pk); self.idx_map.save(store, idx, &(pk.len() as u32)) } fn remove(&self, store: &mut dyn Storage, pk: &[u8], old_data: &T) -> StdResult<()> { - let idx = (self.index)(old_data).joined_extra_key(pk); + let idx = (self.index)(pk, old_data).joined_extra_key(pk); self.idx_map.remove(store, idx); Ok(()) } From a66d96e24ced3e3be6b35497aa6407c0ae2879e6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 16 Aug 2022 21:58:45 +0200 Subject: [PATCH 412/631] Adapt indexed map tests to new multi index fn signature --- packages/storage-macro/tests/index_list.rs | 4 +- packages/storage-plus/src/indexed_map.rs | 46 +++++++++++++++---- packages/storage-plus/src/indexed_snapshot.rs | 20 ++++++-- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-macro/tests/index_list.rs index 57eff5685..224b20551 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-macro/tests/index_list.rs @@ -23,7 +23,7 @@ mod test { let _: IndexedMap = IndexedMap::new( "t", TestIndexes { - id: MultiIndex::new(|t| t.id2, "t", "t_id2"), + id: MultiIndex::new(|_pk, t| t.id2, "t", "t_id2"), addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), }, ); @@ -48,7 +48,7 @@ mod test { let idm: IndexedMap = IndexedMap::new( "t", TestIndexes { - id: MultiIndex::new(|t| t.id2, "t", "t_2"), + id: MultiIndex::new(|_pk, t| t.id2, "t", "t_2"), addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), }, ); diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index ca2ba8b78..d3ba2d695 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -322,7 +322,7 @@ mod test { // Can we make it easier to define this? (less wordy generic) fn build_map<'a>() -> IndexedMap<'a, &'a str, Data, DataIndexes<'a>> { let indexes = DataIndexes { - name: MultiIndex::new(|d| d.name.clone(), "data", "data__name"), + name: MultiIndex::new(|_pk, d| d.name.clone(), "data", "data__name"), age: UniqueIndex::new(|d| d.age, "data__age"), name_lastname: UniqueIndex::new( |d| index_string_tuple(&d.name, &d.last_name), @@ -651,7 +651,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -712,7 +716,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1070,7 +1078,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1125,7 +1137,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1177,7 +1193,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1235,7 +1255,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1316,7 +1340,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedMap::new("data", indexes); @@ -1478,7 +1506,7 @@ mod test { fn composite_key_query() { let indexes = Indexes { secondary: MultiIndex::new( - |secondary| *secondary, + |_pk, secondary| *secondary, "test_map", "test_map__secondary", ), diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs index 89987551e..146fc0d0f 100644 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ b/packages/storage-plus/src/indexed_snapshot.rs @@ -347,7 +347,7 @@ mod test { // Can we make it easier to define this? (less wordy generic) fn build_snapshot_map<'a>() -> IndexedSnapshotMap<'a, &'a str, Data, DataIndexes<'a>> { let indexes = DataIndexes { - name: MultiIndex::new(|d| d.name.as_bytes().to_vec(), "data", "data__name"), + name: MultiIndex::new(|_pk, d| d.name.as_bytes().to_vec(), "data", "data__name"), age: UniqueIndex::new(|d| d.age, "data__age"), name_lastname: UniqueIndex::new( |d| index_string_tuple(&d.name, &d.last_name), @@ -677,7 +677,11 @@ mod test { let mut height = 2; let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); @@ -743,7 +747,11 @@ mod test { let mut height = 2; let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); @@ -1134,7 +1142,11 @@ mod test { let mut store = MockStorage::new(); let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new(|d| index_tuple(&d.name, d.age), "data", "data__name_age"), + name_age: MultiIndex::new( + |_pk, d| index_tuple(&d.name, d.age), + "data", + "data__name_age", + ), }; let map = IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); From ffe22afbcb8ca4473cb3a101306cd9ffd3dd73cd Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 17 Aug 2022 10:46:07 +0200 Subject: [PATCH 413/631] Add test for multi index indexing using pk --- packages/storage-plus/src/indexed_map.rs | 105 +++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index d3ba2d695..851324861 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1557,4 +1557,109 @@ mod test { ); } } + + mod pk_multi_index { + use super::*; + use cosmwasm_std::{Addr, Uint128}; + + struct Indexes<'a> { + // The last type param must match the `IndexedMap` primary key type below + spender: MultiIndex<'a, Addr, Uint128, (Addr, Addr)>, + } + + impl<'a> IndexList for Indexes<'a> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.spender]; + Box::new(v.into_iter()) + } + } + + #[test] + #[cfg(feature = "iterator")] + fn pk_based_index() { + fn pk_index(pk: &[u8]) -> Addr { + let (_owner, spender) = <(Addr, Addr)>::from_slice(pk).unwrap(); // mustn't fail + spender + } + + let indexes = Indexes { + spender: MultiIndex::new( + |pk, _allow| pk_index(pk), + "allowances", + "allowances__spender", + ), + }; + let map = IndexedMap::<(&Addr, &Addr), Uint128, Indexes>::new("allowances", indexes); + let mut store = MockStorage::new(); + + map.save( + &mut store, + (&Addr::unchecked("owner1"), &Addr::unchecked("spender1")), + &Uint128::new(11), + ) + .unwrap(); + map.save( + &mut store, + (&Addr::unchecked("owner1"), &Addr::unchecked("spender2")), + &Uint128::new(12), + ) + .unwrap(); + map.save( + &mut store, + (&Addr::unchecked("owner2"), &Addr::unchecked("spender1")), + &Uint128::new(21), + ) + .unwrap(); + + // Iterate over the main values + let items: Vec<_> = map + .range_raw(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + + // Strip the index from values (for simpler comparison) + let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); + + assert_eq!(items, vec![11, 12, 21]); + + // Iterate over the indexed values + let items: Vec<_> = map + .idx + .spender + .range_raw(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + + // Strip the index from values (for simpler comparison) + let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); + + assert_eq!(items, vec![11, 21, 12]); + + // Prefix over the main values + let items: Vec<_> = map + .prefix(&Addr::unchecked("owner1")) + .range_raw(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + + // Strip the index from values (for simpler comparison) + let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); + + assert_eq!(items, vec![11, 12]); + + // Prefix over the indexed values + let items: Vec<_> = map + .idx + .spender + .prefix(Addr::unchecked("spender1")) + .range_raw(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + + // Strip the index from values (for simpler comparison) + let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); + + assert_eq!(items, vec![11, 21]); + } + } } From 8c677cef7fa562e0d777708da417104757dd2ea7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 17 Aug 2022 10:50:23 +0200 Subject: [PATCH 414/631] Add extra deserializing pk test --- packages/storage-plus/src/indexed_map.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 851324861..8fe7f725c 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -1660,6 +1660,23 @@ mod test { let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); assert_eq!(items, vec![11, 21]); + + // Prefix over the indexed values, and deserialize primary key as well + let items: Vec<_> = map + .idx + .spender + .prefix(Addr::unchecked("spender2")) + .range(&store, None, None, Order::Ascending) + .collect::>() + .unwrap(); + + assert_eq!( + items, + vec![( + (Addr::unchecked("owner1"), Addr::unchecked("spender2")), + Uint128::new(12) + )] + ); } } } From 31818c39e163efdb52828c98b10392341433056b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 17 Aug 2022 11:04:50 +0200 Subject: [PATCH 415/631] Update MIGRATING guide --- MIGRATING.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/MIGRATING.md b/MIGRATING.md index 8fe761275..bfb61d4ff 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -2,6 +2,30 @@ This guide lists API changes between *cw-plus* major releases. +## v0.13.x -> v0.14.0 + +### Breaking Issues / PRs + +- `MultiIndex` index fn params now include the pk [\#670](https://github.com/CosmWasm/cw-plus/issues/670) + +The `idx_fn` param of the `MultiIndex` constructor now has signature `fn(&[u8], &T) -> IK`, where the first param is the +primary key of the index (in raw format), and the second param is the associated value. +That allows us to use the pk or parts of it for building the index key. + +Migration of existing code is straight-forward. Just add an (unused) `_pk` param to the index function definition: + +```diff +fn build_map<'a>() -> IndexedMap<'a, &'a str, Data, DataIndexes<'a>> { + let indexes = DataIndexes { +- name: MultiIndex::new(|d| d.name.clone(), "data", "data__name"), ++ name: MultiIndex::new(|_pk, d| d.name.clone(), "data", "data__name"), + age: UniqueIndex::new(|d| d.age, "data__age"), + name_lastname: UniqueIndex::new( +``` + +If you want to leverage this new functionality, take a look at the `pk_based_index()` test / example +in `src/indexed_map.rs`. + ## v0.11.0 -> v0.12.0 ### Breaking Issues / PRs From 2dbf1c995166f271cb0109b06175df9ccf8d3b54 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 19 Aug 2022 13:35:05 +0200 Subject: [PATCH 416/631] Add (failing) execute after expiration test Backported from flex-multisig --- contracts/cw3-fixed-multisig/src/contract.rs | 83 ++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 629544bda..7cb70b655 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -925,6 +925,89 @@ mod tests { assert_eq!(err, ContractError::WrongCloseStatus {}); } + #[test] + fn proposal_pass_on_expiration() { + let mut deps = mock_dependencies(); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + + let info = mock_info(OWNER, &[]); + setup_test_case(deps.as_mut(), info.clone(), threshold, voting_period).unwrap(); + + // Propose + let bank_msg = BankMsg::Send { + to_address: SOMEBODY.into(), + amount: vec![coin(1, "BTC")], + }; + let msgs = vec![CosmosMsg::Bank(bank_msg)]; + let proposal = ExecuteMsg::Propose { + title: "Pay somebody".to_string(), + description: "Do I pay her?".to_string(), + msgs, + latest: None, + }; + let res = execute(deps.as_mut(), mock_env(), info, proposal).unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.attributes[2].value.parse().unwrap(); + + // Vote it, so it passes after voting period is over + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let info = mock_info(VOTER3, &[]); + let res = execute(deps.as_mut(), mock_env(), info, vote).unwrap(); + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER3) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Open") + ); + + // Wait until the voting period is over + let env = match voting_period { + Duration::Time(duration) => mock_env_time(duration + 1), + Duration::Height(duration) => mock_env_height(duration + 1), + }; + + // Proposal should now be passed + let prop: ProposalResponse = from_binary( + &query( + deps.as_ref(), + env.clone(), + QueryMsg::Proposal { proposal_id }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(prop.status, Status::Passed); + + // Execution should now be possible + let info = mock_info(SOMEBODY, &[]); + let res = execute( + deps.as_mut(), + env, + info, + ExecuteMsg::Execute { proposal_id }, + ) + .unwrap(); + assert_eq!( + res.attributes, + Response::::new() + .add_attribute("action", "execute") + .add_attribute("sender", SOMEBODY) + .add_attribute("proposal_id", proposal_id.to_string()) + .attributes + ) + } + #[test] fn test_close_works() { let mut deps = mock_dependencies(); From 9f3caff54564ccab3befcbc67213e42584ca1df6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 19 Aug 2022 14:20:49 +0200 Subject: [PATCH 417/631] Add (failing) closing passed after expiration not possible checks --- contracts/cw3-fixed-multisig/src/contract.rs | 12 +++++++++++- contracts/cw3-flex-multisig/src/contract.rs | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 7cb70b655..dd3c28644 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -989,8 +989,18 @@ mod tests { .unwrap(); assert_eq!(prop.status, Status::Passed); - // Execution should now be possible + // Closing should NOT be possible let info = mock_info(SOMEBODY, &[]); + let err = execute( + deps.as_mut(), + env.clone(), + info.clone(), + ExecuteMsg::Close { proposal_id }, + ) + .unwrap_err(); + assert_eq!(err, ContractError::WrongCloseStatus {}); + + // Execution should now be possible let res = execute( deps.as_mut(), env, diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 79ac0fc27..c3a333928 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -1394,6 +1394,17 @@ mod tests { .unwrap(); assert_eq!(prop.status, Status::Passed); + // Closing should NOT be possible + let err = app + .execute_contract( + Addr::unchecked(SOMEBODY), + flex_addr.clone(), + &ExecuteMsg::Close { proposal_id }, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::WrongCloseStatus {}, err.downcast().unwrap()); + // Execution should now be possible. let res = app .execute_contract( From 1ef0301a16a7e106ef7ff1e4c97a577eaa4d3ddb Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 19 Aug 2022 10:19:49 +0200 Subject: [PATCH 418/631] Fix: allow execution of passed proposals due to expiration --- contracts/cw3-fixed-multisig/src/contract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index dd3c28644..925eaafb8 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -177,7 +177,7 @@ pub fn execute_vote( pub fn execute_execute( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, proposal_id: u64, ) -> Result { @@ -186,7 +186,7 @@ pub fn execute_execute( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.status != Status::Passed { + if prop.current_status(&env.block) != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } From 64895954912f0346389215d00fdc2a1538ddb0f7 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 19 Aug 2022 11:14:03 +0200 Subject: [PATCH 419/631] Fix: Avoid closing of Passed (through expiration) proposals --- contracts/cw3-fixed-multisig/src/contract.rs | 6 +++++- contracts/cw3-flex-multisig/src/contract.rs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 925eaafb8..1e0809c37 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -213,10 +213,14 @@ pub fn execute_close( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; if [Status::Executed, Status::Rejected, Status::Passed] .iter() - .any(|x| *x == prop.status) + .any(|&s| s == prop.status) { return Err(ContractError::WrongCloseStatus {}); } + // Avoid closing of Passed due to expiration proposals + if prop.current_status(&env.block) == Status::Passed { + return Err(ContractError::WrongCloseStatus {}); + } if !prop.expires.is_expired(&env.block) { return Err(ContractError::NotExpired {}); } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index c3a333928..d9397bf19 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -226,10 +226,14 @@ pub fn execute_close( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; if [Status::Executed, Status::Rejected, Status::Passed] .iter() - .any(|x| *x == prop.status) + .any(|&s| s == prop.status) { return Err(ContractError::WrongCloseStatus {}); } + // Avoid closing of Passed due to expiration proposals + if prop.current_status(&env.block) == Status::Passed { + return Err(ContractError::WrongCloseStatus {}); + } if !prop.expires.is_expired(&env.block) { return Err(ContractError::NotExpired {}); } From 9b43b57168cdd3ebe8a65828e3e184dca801b9bb Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 23 Aug 2022 05:25:32 +0200 Subject: [PATCH 420/631] Update status in passing during execution --- contracts/cw3-fixed-multisig/src/contract.rs | 3 ++- contracts/cw3-flex-multisig/src/contract.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 1e0809c37..d206b9b07 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -186,7 +186,8 @@ pub fn execute_execute( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.current_status(&env.block) != Status::Passed { + prop.update_status(&env.block); + if prop.status != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index d9397bf19..9fbc8eb83 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -196,7 +196,8 @@ pub fn execute_execute( let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.current_status(&env.block) != Status::Passed { + prop.update_status(&env.block); + if prop.status != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } From 9494ad7a1eef1a9df4627e144e58e4be371d763f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 23 Aug 2022 14:27:43 +0200 Subject: [PATCH 421/631] Simplify wrong close status condition --- contracts/cw3-fixed-multisig/src/contract.rs | 5 +---- contracts/cw3-flex-multisig/src/contract.rs | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index d206b9b07..99cb1edbd 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -212,10 +212,7 @@ pub fn execute_close( // anyone can trigger this if the vote passed let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if [Status::Executed, Status::Rejected, Status::Passed] - .iter() - .any(|&s| s == prop.status) - { + if [Status::Executed, Status::Rejected, Status::Passed].contains(&prop.status) { return Err(ContractError::WrongCloseStatus {}); } // Avoid closing of Passed due to expiration proposals diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 9fbc8eb83..a8ae47f70 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -225,10 +225,7 @@ pub fn execute_close( // anyone can trigger this if the vote passed let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if [Status::Executed, Status::Rejected, Status::Passed] - .iter() - .any(|&s| s == prop.status) - { + if [Status::Executed, Status::Rejected, Status::Passed].contains(&prop.status) { return Err(ContractError::WrongCloseStatus {}); } // Avoid closing of Passed due to expiration proposals From 529bfbf14b0ebad17e1a5254c6f4233112d3f035 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 19 Aug 2022 10:46:54 +0200 Subject: [PATCH 422/631] Allow voting on (unexpired) Passed and Rejected proposals For vote tally / statistics --- contracts/cw3-fixed-multisig/src/contract.rs | 45 +++++++++++++++++--- contracts/cw3-flex-multisig/src/contract.rs | 44 ++++++++++++++++--- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 99cb1edbd..1b2c19a29 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -147,9 +147,11 @@ pub fn execute_vote( // ensure proposal exists and can be voted on let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if prop.status != Status::Open { + // Allow voting on Passed and Rejected proposals too, + if ![Status::Open, Status::Passed, Status::Rejected].contains(&prop.status) { return Err(ContractError::NotOpen {}); } + // if they are not expired if prop.expires.is_expired(&env.block) { return Err(ContractError::Expired {}); } @@ -431,6 +433,7 @@ mod tests { const VOTER3: &str = "voter0003"; const VOTER4: &str = "voter0004"; const VOTER5: &str = "voter0005"; + const VOTER6: &str = "voter0006"; const NOWEIGHT_VOTER: &str = "voterxxxx"; const SOMEBODY: &str = "somebody"; @@ -457,6 +460,7 @@ mod tests { voter(VOTER3, 3), voter(VOTER4, 4), voter(VOTER5, 5), + voter(VOTER6, 1), voter(NOWEIGHT_VOTER, 0), ]; @@ -762,10 +766,19 @@ mod tests { .add_attribute("status", "Passed") ); - // non-Open proposals cannot be voted + // Passed proposals can still be voted (while they are not expired or executed) let info = mock_info(VOTER5, &[]); - let err = execute(deps.as_mut(), mock_env(), info, yes_vote).unwrap_err(); - assert_eq!(err, ContractError::NotOpen {}); + let res = execute(deps.as_mut(), mock_env(), info, yes_vote).unwrap(); + + // Verify + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER5) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Passed") + ); // Propose let info = mock_info(OWNER, &[]); @@ -808,7 +821,7 @@ mod tests { let info = mock_info(VOTER4, &[]); let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); - // Verify it is still open as we actually need no votes > 16 - 3 + // Verify it is still open as we actually need no votes > 17 - 3 assert_eq!( res, Response::new() @@ -826,7 +839,7 @@ mod tests { let info = mock_info(VOTER5, &[]); let res = execute(deps.as_mut(), mock_env(), info, no_vote.clone()).unwrap(); - // Verify it is still open as we actually need no votes > 16 - 3 + // Verify it is still open as we actually need no votes > 17 - 3 assert_eq!( res, Response::new() @@ -841,7 +854,7 @@ mod tests { let info = mock_info(VOTER2, &[]); let res = execute(deps.as_mut(), mock_env(), info, no_vote).unwrap(); - // Verify it is rejected as, 15 no votes > 16 - 3 + // Verify it is rejected as, 15 no votes > 17 - 3 assert_eq!( res, Response::new() @@ -850,6 +863,24 @@ mod tests { .add_attribute("proposal_id", proposal_id.to_string()) .add_attribute("status", "Rejected") ); + + // Rejected proposals can still be voted (while they are not expired) + let info = mock_info(VOTER6, &[]); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let res = execute(deps.as_mut(), mock_env(), info, yes_vote).unwrap(); + + // Verify + assert_eq!( + res, + Response::new() + .add_attribute("action", "vote") + .add_attribute("sender", VOTER6) + .add_attribute("proposal_id", proposal_id.to_string()) + .add_attribute("status", "Rejected") + ); } #[test] diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index a8ae47f70..2b473a250 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -151,9 +151,11 @@ pub fn execute_vote( // ensure proposal exists and can be voted on let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if prop.status != Status::Open { + // Allow voting on Passed and Rejected proposals too, + if ![Status::Open, Status::Passed, Status::Rejected].contains(&prop.status) { return Err(ContractError::NotOpen {}); } + // if they are not expired if prop.expires.is_expired(&env.block) { return Err(ContractError::Expired {}); } @@ -1029,11 +1031,20 @@ mod tests { ], ); - // non-Open proposals cannot be voted - let err = app + // Passed proposals can still be voted (while they are not expired or executed) + let res = app .execute_contract(Addr::unchecked(VOTER5), flex_addr.clone(), &yes_vote, &[]) - .unwrap_err(); - assert_eq!(ContractError::NotOpen {}, err.downcast().unwrap()); + .unwrap(); + // Verify + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Passed") + ] + ); // query individual votes // initial (with 0 weight) @@ -1069,7 +1080,7 @@ mod tests { ); // non-voter - let voter = VOTER5.into(); + let voter = SOMEBODY.into(); let vote: VoteResponse = app .wrap() .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) @@ -1096,7 +1107,7 @@ mod tests { // Powerful voter opposes it, so it rejects let res = app - .execute_contract(Addr::unchecked(VOTER4), flex_addr, &no_vote, &[]) + .execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &no_vote, &[]) .unwrap(); assert_eq!( @@ -1108,6 +1119,25 @@ mod tests { ("status", "Rejected"), ], ); + + // Rejected proposals can still be voted (while they are not expired) + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let res = app + .execute_contract(Addr::unchecked(VOTER5), flex_addr, &yes_vote, &[]) + .unwrap(); + + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Rejected"), + ], + ); } #[test] From 90a49010616571f14f7819469000ea342a75a734 Mon Sep 17 00:00:00 2001 From: 0xriku Date: Wed, 24 Aug 2022 18:31:32 -0400 Subject: [PATCH 423/631] Updating broken link to cw3-flex-multisig --- packages/cw4/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cw4/README.md b/packages/cw4/README.md index d0f73d7f4..3cf96ae9e 100644 --- a/packages/cw4/README.md +++ b/packages/cw4/README.md @@ -40,7 +40,7 @@ Only the `admin` may execute any of these function. Thus, by omitting an If we include one, it may often be desired to be a `cw3` contract that uses this group contract as a group. This leads to a bit of chicken-and-egg problem, but we cover how to instantiate that in -[`cw3-flexible-multisig`](../../contracts/cw3-flexible-multisig/README.md#instantiation). +[`cw3-flex-multisig`](../../contracts/cw3-flex-multisig/README.md#instantiation). ## Queries From 827e3d5ba06f30ae00885c134162c09a9b62a5e3 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 16:32:33 +0200 Subject: [PATCH 424/631] Update to cosmwasm 1.1.0-rc.1 --- Cargo.lock | 383 +++++++++++++----------- contracts/cw1-subkeys/Cargo.toml | 4 +- contracts/cw1-whitelist-ng/Cargo.toml | 4 +- contracts/cw1-whitelist/Cargo.toml | 4 +- contracts/cw1155-base/Cargo.toml | 4 +- contracts/cw20-base/Cargo.toml | 4 +- contracts/cw20-ics20/Cargo.toml | 4 +- contracts/cw3-fixed-multisig/Cargo.toml | 4 +- contracts/cw3-flex-multisig/Cargo.toml | 4 +- contracts/cw4-group/Cargo.toml | 4 +- contracts/cw4-stake/Cargo.toml | 4 +- contracts/cw4-stake/src/contract.rs | 6 +- packages/controllers/Cargo.toml | 2 +- packages/controllers/src/claim.rs | 32 +- packages/cw1/Cargo.toml | 4 +- packages/cw1155/Cargo.toml | 4 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 4 +- packages/multi-test/Cargo.toml | 4 +- packages/storage-macro/Cargo.toml | 2 +- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 2 +- 24 files changed, 268 insertions(+), 227 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40c190f9d..365d9ce83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" dependencies = [ "backtrace", ] @@ -51,9 +51,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ "addr2line", "cc", @@ -78,9 +78,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" +checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" [[package]] name = "bitflags" @@ -97,6 +97,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" version = "0.2.17" @@ -111,9 +120,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byteorder" @@ -123,18 +132,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cast" -version = "0.2.7" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" @@ -161,17 +167,17 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.1.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "090841687cec685dd6a1914b8c9504e716b83d2f17a583af6f3b77a8034cfdb1" dependencies = [ - "digest", + "digest 0.10.3", "ed25519-zebra", "k256", "rand_core 0.6.3", @@ -180,32 +186,47 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.1.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "73196b5f87f50ac75eb716ce9f0fc0aaa80394ba742382f7714c38f9b5420e97" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0" +version = "1.1.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" +checksum = "3e420480fd492336e849bf1c24f7339abf12a8e2afa250bc6865d67cd84cf4b4" dependencies = [ + "cosmwasm-schema-derive", "schemars", + "serde", "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.1.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf475a7f85987e1f5ef623c510a39d8d294d1ee6807c68f08d96ada6905e850d" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "cosmwasm-std" -version = "1.0.0" +version = "1.1.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "41e13a4bfb42768d53db5d930ce276356958a8f2d4da89ac44b3841393d1e45b" dependencies = [ "base64", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", "schemars", "serde", @@ -216,9 +237,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.0.0" +version = "1.1.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" +checksum = "9cf3cd03affeaea2e250f431024fff6cee96f1e9c0f79b4202cb6554c917ba00" dependencies = [ "cosmwasm-std", "serde", @@ -226,18 +247,18 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" dependencies = [ "libc", ] [[package]] name = "criterion" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", @@ -261,9 +282,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", "itertools", @@ -271,9 +292,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", @@ -281,9 +302,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -292,26 +313,26 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] @@ -322,9 +343,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -333,13 +354,13 @@ dependencies = [ ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "subtle", + "typenum", ] [[package]] @@ -371,7 +392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", - "digest", + "digest 0.9.0", "rand_core 0.5.1", "subtle", "zeroize", @@ -682,11 +703,12 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" dependencies = [ "const-oid", + "zeroize", ] [[package]] @@ -709,17 +731,28 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", + "subtle", +] + [[package]] name = "dyn-clone" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" +checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "e852f4174d2a8646a0fa8a34b55797856c722f86267deb0aa1e93f7f247f800e" dependencies = [ "der", "elliptic-curve", @@ -737,29 +770,31 @@ dependencies = [ "hex", "rand_core 0.6.3", "serde", - "sha2", + "sha2 0.9.9", "thiserror", "zeroize", ] [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", + "digest 0.10.3", "ff", "generic-array", "group", + "pkcs8", "rand_core 0.6.3", "sec1", "subtle", @@ -768,9 +803,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "rand_core 0.6.3", "subtle", @@ -784,9 +819,9 @@ checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -805,26 +840,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "gimli" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" [[package]] name = "group" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff", "rand_core 0.6.3", @@ -854,12 +889,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac", - "digest", + "digest 0.10.3", ] [[package]] @@ -879,30 +913,29 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "6db2573d3fd3e4cc741affc9b5ce1a8ce36cf29f09f80f36da4309d0ae6d7854" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2", + "sha2 0.10.2", ] [[package]] @@ -913,9 +946,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.125" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "log" @@ -943,9 +976,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler", ] @@ -971,13 +1004,19 @@ dependencies = [ [[package]] name = "object" -version = "0.28.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "memchr", ] +[[package]] +name = "once_cell" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" + [[package]] name = "oorandom" version = "11.1.3" @@ -992,20 +1031,19 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] name = "plotters" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +checksum = "716b4eeb6c4a1d3ecc956f75b43ec2e8e8ba80026413e70a3f41fd3313d3492b" dependencies = [ "num-traits", "plotters-backend", @@ -1016,15 +1054,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -1037,9 +1075,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] @@ -1069,9 +1107,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1112,7 +1150,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.6", + "getrandom 0.2.7", ] [[package]] @@ -1141,9 +1179,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "regex-syntax", ] @@ -1156,15 +1194,15 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" dependencies = [ "crypto-bigint", "hmac", @@ -1177,20 +1215,11 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1203,9 +1232,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" +checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" dependencies = [ "dyn-clone", "schemars_derive", @@ -1215,9 +1244,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" +checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" dependencies = [ "proc-macro2", "quote", @@ -1233,10 +1262,11 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array", "pkcs8", @@ -1246,15 +1276,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.9" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -1280,9 +1310,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -1291,9 +1321,9 @@ dependencies = [ [[package]] name = "serde_derive_internals" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", @@ -1302,11 +1332,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.3", "ryu", "serde", ] @@ -1317,28 +1347,39 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.3", +] + [[package]] name = "signature" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "f0ea32af43239f0d353a7dd75a22d94c329c8cdaafdcb4c1c1335aa10c298a4a" dependencies = [ - "digest", + "digest 0.10.3", "rand_core 0.6.3", ] [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -1358,9 +1399,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.96" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -1378,18 +1419,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -1426,9 +1467,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-width" @@ -1461,15 +1502,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1477,13 +1518,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1492,9 +1533,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1502,9 +1543,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -1515,15 +1556,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -1562,6 +1603,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zeroize" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 3db259ffa..560c6d88a 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library"] } -cosmwasm-std = { version = "1.0.0", features = ["staking"] } +cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 7ca6293cf..a452aa3b6 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -22,11 +22,11 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0", features = ["staking"] } +cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index e64a7751c..2c2c57a03 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0", features = ["staking"] } +cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 44b19e703..4daed8a0f 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw1155 = { path = "../../packages/cw1155", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index ee071fd12..08ba32a88 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index a143085fa..cfcaae353 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -18,11 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0", features = ["stargate"] } +cosmwasm-std = { version = "1.1.0-rc.1", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } schemars = "0.8.1" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 6c0a6928a..db016d6ab 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 2db50dd24..9eb2303ac 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -18,14 +18,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.14.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 125e23477..a23768a9c 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -26,13 +26,13 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 188d9cda6..e7ce93bde 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -26,14 +26,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 6b51897b5..408f3265c 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -524,13 +524,13 @@ mod tests { // this tests the member queries fn assert_stake(deps: Deps, user1_stake: u128, user2_stake: u128, user3_stake: u128) { let stake1 = query_staked(deps, USER1.into()).unwrap(); - assert_eq!(stake1.stake, user1_stake.into()); + assert_eq!(stake1.stake, Uint128::from(user1_stake)); let stake2 = query_staked(deps, USER2.into()).unwrap(); - assert_eq!(stake2.stake, user2_stake.into()); + assert_eq!(stake2.stake, Uint128::from(user2_stake)); let stake3 = query_staked(deps, USER3.into()).unwrap(); - assert_eq!(stake3.stake, user3_stake.into()); + assert_eq!(stake3.stake, Uint128::from(user3_stake)); } #[test] diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 56759d389..723b792c0 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -11,7 +11,7 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } cw-utils = { path = "../utils", version = "0.14.0" } cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } schemars = "0.8.1" diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index 01083fecb..1e6c4c472 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -110,7 +110,7 @@ mod test { #[test] fn can_create_claim() { let claim = Claim::new(TEST_AMOUNT, TEST_EXPIRATION); - assert_eq!(claim.amount, TEST_AMOUNT.into()); + assert_eq!(claim.amount, Uint128::from(TEST_AMOUNT)); assert_eq!(claim.release_at, TEST_EXPIRATION); } @@ -150,7 +150,7 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, TEST_AMOUNT.into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); // Adding another claim to same address, make sure that both claims are saved. @@ -169,9 +169,9 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, TEST_AMOUNT.into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); - assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[1].release_at, TEST_EXPIRATION); // Adding another claim to different address, make sure that other address only has one claim. @@ -262,9 +262,9 @@ mod test { assert_eq!(amount, Uint128::zero()); assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); } @@ -308,9 +308,9 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); - assert_eq!(amount, TEST_AMOUNT.into()); + assert_eq!(amount, Uint128::from(TEST_AMOUNT)); assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(100)); } @@ -354,7 +354,7 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); - assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + assert_eq!(amount, Uint128::from(TEST_AMOUNT + TEST_AMOUNT + 100)); assert_eq!(saved_claims.len(), 0); } @@ -400,9 +400,9 @@ mod test { assert_eq!(amount, Uint128::zero()); assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, (TEST_AMOUNT).into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); } @@ -446,7 +446,7 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); - assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + assert_eq!(amount, Uint128::from(TEST_AMOUNT + TEST_AMOUNT + 100)); assert_eq!(saved_claims.len(), 0); } @@ -484,14 +484,14 @@ mod test { Some((TEST_AMOUNT + 50).into()), ) .unwrap(); - assert_eq!(amount, (TEST_AMOUNT).into()); + assert_eq!(amount, Uint128::from(TEST_AMOUNT)); let saved_claims = claims .0 .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); } @@ -536,9 +536,9 @@ mod test { .load(deps.as_mut().storage, &Addr::unchecked("addr")) .unwrap(); assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, (TEST_AMOUNT).into()); + assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT)); assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(5)); } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 217a478ed..bdf935f19 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,9 +9,9 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 0ee87d3e8..12742425d 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 961ed3733..d2e832746 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.0.0", default-features = false } +cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index e18423a89..49b2a9006 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index bb9532bc0..83fe57e9b 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 668899336..4f64679e7 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -10,9 +10,9 @@ homepage = "https://cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index bfc5c83cf..f8bcd7ca1 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -19,8 +19,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0"} -cosmwasm-std = { version = "1.0.0", features = ["staking"] } -cosmwasm-storage = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } +cosmwasm-storage = { version = "1.1.0-rc.1" } itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index 76e81f45e..ab18fc4af 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -17,5 +17,5 @@ syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] cw-storage-plus = { version = "<=0.14.0, >=0.13.4", path = "../storage-plus" } -cosmwasm-std = { version = "1.0.0", default-features = false } +cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 3d9b4a14e..8ec378573 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -18,7 +18,7 @@ macro = ["cw-storage-macro"] bench = false [dependencies] -cosmwasm-std = { version = "1.0.0", default-features = false } +cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } cw-storage-macro = { version = "0.14.0", optional = true, path = "../storage-macro" } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index aec23b9d7..758e38d6a 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -11,7 +11,7 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.0.0" } +cosmwasm-std = { version = "1.1.0-rc.1" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } schemars = "0.8.1" semver = "1" From 339c9d5fb0f3de95b8b61e9c56127d2cd646e644 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 17:06:34 +0200 Subject: [PATCH 425/631] Use the new #[cw_serde] macro for packages --- Cargo.lock | 3 +++ packages/controllers/Cargo.toml | 3 ++- packages/controllers/src/admin.rs | 4 ++-- packages/controllers/src/claim.rs | 8 +++----- packages/controllers/src/hooks.rs | 4 ++-- packages/cw1/Cargo.toml | 6 ++---- packages/cw1/src/helpers.rs | 6 ++---- packages/cw1/src/msg.rs | 5 ++--- packages/cw1/src/query.rs | 7 +++---- packages/cw1155/Cargo.toml | 4 +--- packages/cw1155/src/msg.rs | 9 +++++---- packages/cw1155/src/query.rs | 23 ++++++++++++----------- packages/cw1155/src/receiver.rs | 17 +++++++++-------- packages/cw2/Cargo.toml | 1 + packages/cw2/src/lib.rs | 6 ++---- packages/cw20/Cargo.toml | 6 ++---- packages/cw20/src/balance.rs | 9 +++++---- packages/cw20/src/coin.rs | 9 +++++---- packages/cw20/src/denom.rs | 9 +++++---- packages/cw20/src/helpers.rs | 7 ++++--- packages/cw20/src/logo.rs | 17 +++++++++-------- packages/cw20/src/msg.rs | 9 +++++---- packages/cw20/src/query.rs | 19 ++++++++++--------- packages/cw20/src/receiver.rs | 13 +++++++------ packages/cw3/Cargo.toml | 6 ++---- packages/cw3/src/helpers.rs | 7 ++++--- packages/cw3/src/msg.rs | 7 ++++--- packages/cw3/src/query.rs | 22 +++++++++++----------- packages/cw4/Cargo.toml | 6 ++---- packages/cw4/src/helpers.rs | 6 ++---- packages/cw4/src/hook.rs | 14 +++++++------- packages/cw4/src/msg.rs | 6 ++---- packages/cw4/src/query.rs | 22 ++++++++++++---------- packages/multi-test/Cargo.toml | 2 +- packages/multi-test/src/bank.rs | 2 +- packages/multi-test/src/error.rs | 2 +- packages/multi-test/src/staking.rs | 2 +- packages/multi-test/src/test_helpers.rs | 2 +- packages/multi-test/src/wasm.rs | 4 ++-- packages/storage-plus/src/map.rs | 2 +- packages/storage-plus/src/snapshot/mod.rs | 4 ++-- packages/utils/Cargo.toml | 5 +++-- packages/utils/src/balance.rs | 6 +++--- packages/utils/src/expiration.rs | 12 +++++------- packages/utils/src/parse_reply.rs | 6 +++--- packages/utils/src/payment.rs | 2 +- packages/utils/src/scheduled.rs | 8 +++----- packages/utils/src/threshold.rs | 10 +++------- 48 files changed, 180 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 365d9ce83..fb6fd8a45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -402,6 +402,7 @@ dependencies = [ name = "cw-controllers" version = "0.14.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -453,6 +454,7 @@ dependencies = [ name = "cw-utils" version = "0.14.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw2", @@ -558,6 +560,7 @@ dependencies = [ name = "cw2" version = "0.14.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 723b792c0..03feddadd 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -11,7 +11,8 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" cw-utils = { path = "../utils", version = "0.14.0" } cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } schemars = "0.8.1" diff --git a/packages/controllers/src/admin.rs b/packages/controllers/src/admin.rs index e503747a1..7586e5984 100644 --- a/packages/controllers/src/admin.rs +++ b/packages/controllers/src/admin.rs @@ -1,8 +1,8 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::fmt; use thiserror::Error; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, }; @@ -10,7 +10,7 @@ use cw_storage_plus::Item; // TODO: should the return values end up in utils, so eg. cw4 can import them as well as this module? /// Returned from Admin.query_admin() -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AdminResponse { pub admin: Option, } diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index 1e6c4c472..1c707e624 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -1,18 +1,16 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, CustomQuery, Deps, StdResult, Storage, Uint128}; use cw_storage_plus::Map; use cw_utils::Expiration; // TODO: pull into utils? -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct ClaimsResponse { pub claims: Vec, } // TODO: pull into utils? -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Claim { pub amount: Uint128, pub release_at: Expiration, diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index e56985c25..fa7cf964c 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -1,8 +1,8 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::fmt; use thiserror::Error; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, Storage, SubMsg, @@ -13,7 +13,7 @@ use crate::admin::{Admin, AdminError}; // this is copied from cw4 // TODO: pull into utils as common dep -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct HooksResponse { pub hooks: Vec, } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index bdf935f19..6d839df43 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,9 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw1/src/helpers.rs b/packages/cw1/src/helpers.rs index 82b615f28..e46ecb5e2 100644 --- a/packages/cw1/src/helpers.rs +++ b/packages/cw1/src/helpers.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::Cw1ExecuteMsg; @@ -9,7 +7,7 @@ use crate::msg::Cw1ExecuteMsg; /// for working with this. /// /// If you wish to persist this, convert to Cw1CanonicalContract via .canonical() -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw1Contract(pub Addr); impl Cw1Contract { diff --git a/packages/cw1/src/msg.rs b/packages/cw1/src/msg.rs index b6134e51f..62f65f4d2 100644 --- a/packages/cw1/src/msg.rs +++ b/packages/cw1/src/msg.rs @@ -1,11 +1,10 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw1ExecuteMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, diff --git a/packages/cw1/src/query.rs b/packages/cw1/src/query.rs index 749ab73f7..39b291705 100644 --- a/packages/cw1/src/query.rs +++ b/packages/cw1/src/query.rs @@ -1,11 +1,10 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw1QueryMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -16,7 +15,7 @@ where CanExecute { sender: String, msg: CosmosMsg }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct CanExecuteResponse { pub can_execute: bool, } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 12742425d..55b3b1f27 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -10,9 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cosmwasm-schema = "1.1.0-rc.1" cosmwasm-std = { version = "1.1.0-rc.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw1155/src/msg.rs b/packages/cw1155/src/msg.rs index ab087dd40..29d873ec0 100644 --- a/packages/cw1155/src/msg.rs +++ b/packages/cw1155/src/msg.rs @@ -1,13 +1,14 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Binary, Uint128}; use cw_utils::Expiration; pub type TokenId = String; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Cw1155ExecuteMsg { /// SendFrom is a base message to move tokens, /// if `env.sender` is the owner or has sufficient pre-approval. diff --git a/packages/cw1155/src/query.rs b/packages/cw1155/src/query.rs index 059d18899..9f58ccb3d 100644 --- a/packages/cw1155/src/query.rs +++ b/packages/cw1155/src/query.rs @@ -1,13 +1,14 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::Uint128; use cw_utils::Expiration; use crate::msg::TokenId; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Cw1155QueryMsg { /// Returns the current balance of the given address, 0 if unset. /// Return type: BalanceResponse. @@ -53,17 +54,17 @@ pub enum Cw1155QueryMsg { }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct BalanceResponse { pub balance: Uint128, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct BatchBalanceResponse { pub balances: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Approval { /// Account that can transfer/send the token pub spender: String, @@ -71,23 +72,23 @@ pub struct Approval { pub expires: Expiration, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ApprovedForAllResponse { pub operators: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct IsApprovedForAllResponse { pub approved: bool, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct TokenInfoResponse { /// Should be a url point to a json file pub url: String, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct TokensResponse { /// Contains all token_ids in lexicographical ordering /// If there are more than `limit`, use `start_from` in future queries diff --git a/packages/cw1155/src/receiver.rs b/packages/cw1155/src/receiver.rs index 86649c93d..e4ffff720 100644 --- a/packages/cw1155/src/receiver.rs +++ b/packages/cw1155/src/receiver.rs @@ -1,13 +1,14 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; use crate::msg::TokenId; /// Cw1155ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub struct Cw1155ReceiveMsg { /// The account that executed the send message pub operator: String, @@ -38,8 +39,8 @@ impl Cw1155ReceiveMsg { } /// Cw1155BatchReceiveMsg should be de/serialized under `BatchReceive()` variant in a ExecuteMsg -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub struct Cw1155BatchReceiveMsg { pub operator: String, pub from: Option, @@ -67,8 +68,8 @@ impl Cw1155BatchReceiveMsg { } // This is just a helper to properly serialize the above message -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + enum ReceiverExecuteMsg { Receive(Cw1155ReceiveMsg), BatchReceive(Cw1155BatchReceiveMsg), diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index d2e832746..66b87431d 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] +cosmwasm-schema = "1.1.0-rc.1" cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index 9ffc7dc62..f6c55ff79 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -1,12 +1,10 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Empty, Querier, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery}; use cw_storage_plus::Item; pub const CONTRACT: Item = Item::new("contract_info"); -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ContractVersion { /// contract is the crate name of the implementing contract, eg. `crate:cw20-base` /// we will use other prefixes for other languages, and their standard global namespacing diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 49b2a9006..feb0d9ffc 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -10,9 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw20/src/balance.rs b/packages/cw20/src/balance.rs index e59c0b343..2690e09a8 100644 --- a/packages/cw20/src/balance.rs +++ b/packages/cw20/src/balance.rs @@ -1,14 +1,15 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::Coin; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + use std::fmt; use cw_utils::NativeBalance; use crate::Cw20CoinVerified; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Balance { Native(NativeBalance), Cw20(Cw20CoinVerified), diff --git a/packages/cw20/src/coin.rs b/packages/cw20/src/coin.rs index 54d4ff90a..324826096 100644 --- a/packages/cw20/src/coin.rs +++ b/packages/cw20/src/coin.rs @@ -1,10 +1,11 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; use std::fmt; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Cw20Coin { pub address: String, pub amount: Uint128, @@ -22,7 +23,7 @@ impl fmt::Display for Cw20Coin { } } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Cw20CoinVerified { pub address: Addr, pub amount: Uint128, diff --git a/packages/cw20/src/denom.rs b/packages/cw20/src/denom.rs index 1b4e001d2..94f840c5e 100644 --- a/packages/cw20/src/denom.rs +++ b/packages/cw20/src/denom.rs @@ -1,9 +1,10 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] + + +#[cw_serde] + pub enum Denom { Native(String), Cw20(Addr), diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index f1e3df19b..e7db84ca0 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -1,6 +1,7 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ to_binary, Addr, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, Uint128, WasmMsg, WasmQuery, @@ -15,7 +16,7 @@ use crate::{ /// for working with this. /// /// If you wish to persist this, convert to Cw20CanonicalContract via .canonical() -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw20Contract(pub Addr); impl Cw20Contract { diff --git a/packages/cw20/src/logo.rs b/packages/cw20/src/logo.rs index 6f5007068..8f1be205d 100644 --- a/packages/cw20/src/logo.rs +++ b/packages/cw20/src/logo.rs @@ -1,10 +1,11 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::Binary; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + /// This is used for uploading logo data, or setting it in InstantiateData -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Logo { /// A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL. Url(String), @@ -14,8 +15,8 @@ pub enum Logo { /// This is used to store the logo on the blockchain in an accepted format. /// Enforce maximum size of 5KB on all variants. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum EmbeddedLogo { /// Store the Logo as an SVG file. The content must conform to the spec /// at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics @@ -28,8 +29,8 @@ pub enum EmbeddedLogo { /// This is used to display logo info, provide a link or inform there is one /// that can be downloaded from the blockchain itself -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum LogoInfo { /// A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL. Url(String), diff --git a/packages/cw20/src/msg.rs b/packages/cw20/src/msg.rs index f2f9708c9..1d8087235 100644 --- a/packages/cw20/src/msg.rs +++ b/packages/cw20/src/msg.rs @@ -1,12 +1,13 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + use crate::logo::Logo; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Binary, Uint128}; use cw_utils::Expiration; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Cw20ExecuteMsg { /// Transfer is a base message to move tokens to another account without triggering actions Transfer { recipient: String, amount: Uint128 }, diff --git a/packages/cw20/src/query.rs b/packages/cw20/src/query.rs index 84ab604b1..425099bb4 100644 --- a/packages/cw20/src/query.rs +++ b/packages/cw20/src/query.rs @@ -1,13 +1,14 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Binary, Uint128}; use crate::logo::LogoInfo; use cw_utils::Expiration; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Cw20QueryMsg { /// Returns the current balance of the given address, 0 if unset. /// Return type: BalanceResponse. @@ -50,12 +51,12 @@ pub enum Cw20QueryMsg { }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct BalanceResponse { pub balance: Uint128, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct TokenInfoResponse { pub name: String, pub symbol: String, @@ -69,7 +70,7 @@ pub struct AllowanceResponse { pub expires: Expiration, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct MinterResponse { pub minter: String, /// cap is a hard cap on total supply that can be achieved by minting. @@ -92,13 +93,13 @@ pub struct MarketingInfoResponse { /// When we download an embedded logo, we get this response type. /// We expect a SPA to be able to accept this info and display it. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct DownloadLogoResponse { pub mime_type: String, pub data: Binary, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AllowanceInfo { pub spender: String, pub allowance: Uint128, @@ -110,7 +111,7 @@ pub struct AllAllowancesResponse { pub allowances: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct SpenderAllowanceInfo { pub owner: String, pub allowance: Uint128, @@ -122,7 +123,7 @@ pub struct AllSpenderAllowancesResponse { pub allowances: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] pub struct AllAccountsResponse { pub accounts: Vec, } diff --git a/packages/cw20/src/receiver.rs b/packages/cw20/src/receiver.rs index dc8370b63..d44cd78e6 100644 --- a/packages/cw20/src/receiver.rs +++ b/packages/cw20/src/receiver.rs @@ -1,11 +1,12 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; /// Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub struct Cw20ReceiveMsg { pub sender: String, pub amount: Uint128, @@ -32,8 +33,8 @@ impl Cw20ReceiveMsg { } // This is just a helper to properly serialize the above message -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + enum ReceiverExecuteMsg { Receive(Cw20ReceiveMsg), } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 83fe57e9b..10b89cc6d 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -10,9 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw3/src/helpers.rs b/packages/cw3/src/helpers.rs index 3bc56d10b..d2c08cc64 100644 --- a/packages/cw3/src/helpers.rs +++ b/packages/cw3/src/helpers.rs @@ -1,6 +1,7 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::{Cw3ExecuteMsg, Vote}; @@ -13,7 +14,7 @@ use cw_utils::Expiration; /// /// FIXME: Cw3Contract currently only supports CosmosMsg. When we actually /// use this in some consuming code, we should make it generic over CosmosMsg. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw3Contract(pub Addr); impl Cw3Contract { diff --git a/packages/cw3/src/msg.rs b/packages/cw3/src/msg.rs index 0811690fb..32b9a95b8 100644 --- a/packages/cw3/src/msg.rs +++ b/packages/cw3/src/msg.rs @@ -2,11 +2,12 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; use cw_utils::Expiration; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + pub enum Cw3ExecuteMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -30,7 +31,7 @@ where }, } -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] +#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, JsonSchema, Debug)] #[serde(rename_all = "lowercase")] pub enum Vote { /// Marks support for the proposal. diff --git a/packages/cw3/src/query.rs b/packages/cw3/src/query.rs index 27850d757..f1a5b9383 100644 --- a/packages/cw3/src/query.rs +++ b/packages/cw3/src/query.rs @@ -2,13 +2,13 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; use cw_utils::{Expiration, ThresholdResponse}; use crate::msg::Vote; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw3QueryMsg { /// Returns the threshold rules that would be used for a new proposal that was /// opened right now. The threshold rules do not change often, but the `total_weight` @@ -52,7 +52,7 @@ pub enum Cw3QueryMsg { /// Note, if you are storing custom messages in the proposal, /// the querier needs to know what possible custom message types /// those are in order to parse the response -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ProposalResponse where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -69,7 +69,7 @@ where pub threshold: ThresholdResponse, } -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] +#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, JsonSchema, Debug)] #[serde(rename_all = "lowercase")] #[repr(u8)] pub enum Status { @@ -85,19 +85,19 @@ pub enum Status { Executed = 5, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ProposalListResponse { pub proposals: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoteListResponse { pub votes: Vec, } /// Returns the vote (opinion as well as weight counted) as well as /// the address of the voter who submitted it -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoteInfo { pub proposal_id: u64, pub voter: String, @@ -105,22 +105,22 @@ pub struct VoteInfo { pub weight: u64, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoteResponse { pub vote: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoterResponse { pub weight: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoterListResponse { pub voters: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct VoterDetail { pub addr: String, pub weight: u64, diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 4f64679e7..cc5d212c8 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -10,9 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } diff --git a/packages/cw4/src/helpers.rs b/packages/cw4/src/helpers.rs index 0761e5c39..57dc4d069 100644 --- a/packages/cw4/src/helpers.rs +++ b/packages/cw4/src/helpers.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, WasmMsg, WasmQuery, @@ -17,7 +15,7 @@ use cw_storage_plus::{Item, Map}; /// for working with cw4 contracts /// /// If you wish to persist this, convert to Cw4CanonicalContract via .canonical() -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw4Contract(pub Addr); impl Cw4Contract { diff --git a/packages/cw4/src/hook.rs b/packages/cw4/src/hook.rs index e28fdb5c3..80acac001 100644 --- a/packages/cw4/src/hook.rs +++ b/packages/cw4/src/hook.rs @@ -1,6 +1,7 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + + +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; /// MemberDiff shows the old and new states for a given cw4 member @@ -8,7 +9,7 @@ use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; /// old = None, new = Some -> Insert /// old = Some, new = Some -> Update /// old = Some, new = None -> Delete -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct MemberDiff { pub key: String, pub old: Option, @@ -27,8 +28,7 @@ impl MemberDiff { /// MemberChangedHookMsg should be de/serialized under `MemberChangedHook()` variant in a ExecuteMsg. /// This contains a list of all diffs on the given transaction. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MemberChangedHookMsg { pub diffs: Vec, } @@ -61,8 +61,8 @@ impl MemberChangedHookMsg { } // This is just a helper to properly serialize the above message -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] + enum MemberChangedExecuteMsg { MemberChangedHook(MemberChangedHookMsg), } diff --git a/packages/cw4/src/msg.rs b/packages/cw4/src/msg.rs index 291857ce7..ba7ded072 100644 --- a/packages/cw4/src/msg.rs +++ b/packages/cw4/src/msg.rs @@ -1,8 +1,6 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw4ExecuteMsg { /// Change the admin UpdateAdmin { admin: Option }, diff --git a/packages/cw4/src/query.rs b/packages/cw4/src/query.rs index d82734264..337c30e59 100644 --- a/packages/cw4/src/query.rs +++ b/packages/cw4/src/query.rs @@ -1,8 +1,10 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; + + + + +#[cw_serde] -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] pub enum Cw4QueryMsg { /// Return AdminResponse Admin {}, @@ -22,7 +24,7 @@ pub enum Cw4QueryMsg { Hooks {}, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AdminResponse { pub admin: Option, } @@ -30,28 +32,28 @@ pub struct AdminResponse { /// A group member has a weight associated with them. /// This may all be equal, or may have meaning in the app that /// makes use of the group (eg. voting power) -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Member { pub addr: String, pub weight: u64, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct MemberListResponse { pub members: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct MemberResponse { pub weight: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct TotalWeightResponse { pub weight: u64, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct HooksResponse { pub hooks: Vec, } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index f8bcd7ca1..c1a07b88c 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,7 +20,7 @@ backtrace = ["anyhow/backtrace"] cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0"} cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } -cosmwasm-storage = { version = "1.1.0-rc.1" } +cosmwasm-storage = "1.1.0-rc.1" itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs index 17cea14fa..71493d2c0 100644 --- a/packages/multi-test/src/bank.rs +++ b/packages/multi-test/src/bank.rs @@ -19,7 +19,7 @@ const BALANCES: Map<&Addr, NativeBalance> = Map::new("balances"); pub const NAMESPACE_BANK: &[u8] = b"bank"; // WIP -#[derive(Clone, std::fmt::Debug, PartialEq, JsonSchema)] +#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub enum BankSudo { Mint { to_address: String, diff --git a/packages/multi-test/src/error.rs b/packages/multi-test/src/error.rs index 8c4a6675e..f0bd0920d 100644 --- a/packages/multi-test/src/error.rs +++ b/packages/multi-test/src/error.rs @@ -1,7 +1,7 @@ use cosmwasm_std::{WasmMsg, WasmQuery}; use thiserror::Error; -#[derive(Debug, Error, PartialEq)] +#[derive(Debug, Error, PartialEq, Eq)] pub enum Error { #[error("Empty attribute key. Value: {value}")] EmptyAttributeKey { value: String }, diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index bf501caa9..20254a87e 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -5,7 +5,7 @@ use crate::module::FailingModule; use crate::Module; // We need to expand on this, but we will need this to properly test out staking -#[derive(Clone, std::fmt::Debug, PartialEq, JsonSchema)] +#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub enum StakingSudo { Slash { validator: String, diff --git a/packages/multi-test/src/test_helpers.rs b/packages/multi-test/src/test_helpers.rs index 7bbad2f76..cb551197b 100644 --- a/packages/multi-test/src/test_helpers.rs +++ b/packages/multi-test/src/test_helpers.rs @@ -10,7 +10,7 @@ pub mod contracts; pub struct EmptyMsg {} /// This is just a demo place so we can test custom message handling -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename = "snake_case")] pub enum CustomMsg { SetName { name: String }, diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index cdbd06143..618e2739d 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -31,7 +31,7 @@ const CONTRACTS: Map<&Addr, ContractData> = Map::new("contracts"); pub const NAMESPACE_WASM: &[u8] = b"wasm"; const CONTRACT_ATTR: &str = "_contract_addr"; -#[derive(Clone, std::fmt::Debug, PartialEq, JsonSchema)] +#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub struct WasmSudo { pub contract_addr: Addr, pub msg: Binary, @@ -48,7 +48,7 @@ impl WasmSudo { /// Contract Data includes information about contract, equivalent of `ContractInfo` in wasmd /// interface. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractData { /// Identifier of stored contract code pub code_id: usize, diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 67d243af0..4dcc5398b 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -582,7 +582,7 @@ mod test { // Manually add a broken key (invalid utf-8) store.set( - &*[ + &[ [0u8, PEOPLE_STR_KEY.len() as u8].as_slice(), PEOPLE_STR_KEY.as_bytes(), b"\xddim", diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs index d992743b9..7fccfea7d 100644 --- a/packages/storage-plus/src/snapshot/mod.rs +++ b/packages/storage-plus/src/snapshot/mod.rs @@ -160,7 +160,7 @@ where } } -#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)] pub enum Strategy { EveryBlock, Never, @@ -172,7 +172,7 @@ pub enum Strategy { Selected, } -#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct ChangeSet { pub old: Option, } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 758e38d6a..26817784d 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -11,12 +11,13 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0-rc.1" +cosmwasm-std = "1.1.0-rc.1" cw2 = { path = "../../packages/cw2", version = "0.14.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.21" } +thiserror = "1.0.21" [dev-dependencies] cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } diff --git a/packages/utils/src/balance.rs b/packages/utils/src/balance.rs index f37b849fc..16a15d561 100644 --- a/packages/utils/src/balance.rs +++ b/packages/utils/src/balance.rs @@ -1,12 +1,12 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::{fmt, ops}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, OverflowError, OverflowOperation, StdError, StdResult, Uint128}; // Balance wraps Vec and provides some nice helpers. It mutates the Vec and can be // unwrapped when done. -#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, JsonSchema)] +#[cw_serde] +#[derive(Default)] pub struct NativeBalance(pub Vec); impl NativeBalance { diff --git a/packages/utils/src/expiration.rs b/packages/utils/src/expiration.rs index 4cb53fc39..fe1d707dc 100644 --- a/packages/utils/src/expiration.rs +++ b/packages/utils/src/expiration.rs @@ -1,16 +1,14 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{BlockInfo, StdError, StdResult, Timestamp}; use std::cmp::Ordering; use std::fmt; use std::ops::{Add, Mul}; -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] /// Expiration represents a point in time when some event happens. /// It can compare with a BlockInfo and will return is_expired() == true /// once the condition is hit (and for every block in the future) +#[cw_serde] +#[derive(Copy)] pub enum Expiration { /// AtHeight will expire when `env.block.height` >= height AtHeight(u64), @@ -88,8 +86,8 @@ pub const WEEK: Duration = Duration::Time(7 * 24 * 60 * 60); /// Duration is a delta of time. You can add it to a BlockInfo or Expiration to /// move that further in the future. Note that an height-based Duration and /// a time-based Expiration cannot be combined -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(Copy)] pub enum Duration { Height(u64), /// Time in seconds diff --git a/packages/utils/src/parse_reply.rs b/packages/utils/src/parse_reply.rs index 468053de2..f52d18933 100644 --- a/packages/utils/src/parse_reply.rs +++ b/packages/utils/src/parse_reply.rs @@ -7,13 +7,13 @@ const WIRE_TYPE_LENGTH_DELIMITED: u8 = 2; // Up to 9 bytes of varints as a practical limit (https://github.com/multiformats/unsigned-varint#practical-maximum-of-9-bytes-for-security) const VARINT_MAX_BYTES: usize = 9; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct MsgInstantiateContractResponse { pub contract_address: String, pub data: Option, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct MsgExecuteContractResponse { pub data: Option, } @@ -152,7 +152,7 @@ pub fn parse_execute_response_data( Ok(MsgExecuteContractResponse { data: inner_data }) } -#[derive(Error, Debug, PartialEq)] +#[derive(Error, Debug, PartialEq, Eq)] pub enum ParseReplyError { #[error("Failure response from sub-message: {0}")] SubMsgFailure(String), diff --git a/packages/utils/src/payment.rs b/packages/utils/src/payment.rs index 27e8a1063..f6ccdd201 100644 --- a/packages/utils/src/payment.rs +++ b/packages/utils/src/payment.rs @@ -52,7 +52,7 @@ pub fn may_pay(info: &MessageInfo, denom: &str) -> Result } } -#[derive(Error, Debug, PartialEq)] +#[derive(Error, Debug, PartialEq, Eq)] pub enum PaymentError { #[error("Must send reserve token '{0}'")] MissingDenom(String), diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs index c8c6ca4bb..f96794cdb 100644 --- a/packages/utils/src/scheduled.rs +++ b/packages/utils/src/scheduled.rs @@ -1,17 +1,15 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - use crate::Duration; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{BlockInfo, StdError, StdResult, Timestamp}; use std::cmp::Ordering; use std::fmt; use std::ops::Add; -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] /// Scheduled represents a point in time when an event happens. /// It can compare with a BlockInfo and will return is_triggered() == true /// once the condition is hit (and for every block in the future) +#[cw_serde] +#[derive(Copy)] pub enum Scheduled { /// AtHeight will schedule when `env.block.height` >= height AtHeight(u64), diff --git a/packages/utils/src/threshold.rs b/packages/utils/src/threshold.rs index b919f7a02..312a298e0 100644 --- a/packages/utils/src/threshold.rs +++ b/packages/utils/src/threshold.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Decimal, StdError}; use thiserror::Error; @@ -11,8 +9,7 @@ use thiserror::Error; /// the block at which the proposal starts (this is likely the responsibility of a /// correct cw4 implementation). /// See also `ThresholdResponse` in the cw3 spec. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Threshold { /// Declares that a fixed weight of Yes votes is needed to pass. /// See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details. @@ -107,8 +104,7 @@ fn valid_quorum(percent: &Decimal) -> Result<(), ThresholdError> { /// individual voter used in tallying should be snapshotted at the beginning of /// the block at which the proposal starts (this is likely the responsibility of a /// correct cw4 implementation). -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ThresholdResponse { /// Declares that a fixed weight of yes votes is needed to pass. /// It does not matter how many no votes are cast, or how many do not vote, From 58d963e3e1d865a1232d7b8ac3672eb40f5463c2 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 17:45:38 +0200 Subject: [PATCH 426/631] cargo fmt --- packages/cw1155/src/msg.rs | 3 --- packages/cw1155/src/query.rs | 3 --- packages/cw1155/src/receiver.rs | 3 --- packages/cw20/src/balance.rs | 1 - packages/cw20/src/coin.rs | 3 --- packages/cw20/src/denom.rs | 2 -- packages/cw20/src/helpers.rs | 3 --- packages/cw20/src/logo.rs | 2 -- packages/cw20/src/msg.rs | 3 --- packages/cw20/src/receiver.rs | 3 --- packages/cw3/src/helpers.rs | 3 --- packages/cw4/src/hook.rs | 3 --- packages/cw4/src/query.rs | 3 --- 13 files changed, 35 deletions(-) diff --git a/packages/cw1155/src/msg.rs b/packages/cw1155/src/msg.rs index 29d873ec0..e8ddce34b 100644 --- a/packages/cw1155/src/msg.rs +++ b/packages/cw1155/src/msg.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{Binary, Uint128}; use cw_utils::Expiration; diff --git a/packages/cw1155/src/query.rs b/packages/cw1155/src/query.rs index 9f58ccb3d..12cdb99f2 100644 --- a/packages/cw1155/src/query.rs +++ b/packages/cw1155/src/query.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::Uint128; use cw_utils::Expiration; diff --git a/packages/cw1155/src/receiver.rs b/packages/cw1155/src/receiver.rs index e4ffff720..c56dab43a 100644 --- a/packages/cw1155/src/receiver.rs +++ b/packages/cw1155/src/receiver.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; diff --git a/packages/cw20/src/balance.rs b/packages/cw20/src/balance.rs index 2690e09a8..110de1b01 100644 --- a/packages/cw20/src/balance.rs +++ b/packages/cw20/src/balance.rs @@ -1,7 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Coin; - use std::fmt; use cw_utils::NativeBalance; diff --git a/packages/cw20/src/coin.rs b/packages/cw20/src/coin.rs index 324826096..09d461ec7 100644 --- a/packages/cw20/src/coin.rs +++ b/packages/cw20/src/coin.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; use std::fmt; diff --git a/packages/cw20/src/denom.rs b/packages/cw20/src/denom.rs index 94f840c5e..f0351c665 100644 --- a/packages/cw20/src/denom.rs +++ b/packages/cw20/src/denom.rs @@ -1,8 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; - - #[cw_serde] pub enum Denom { diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index e7db84ca0..f38ef3386 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{ to_binary, Addr, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, Uint128, WasmMsg, diff --git a/packages/cw20/src/logo.rs b/packages/cw20/src/logo.rs index 8f1be205d..4ed19a5e4 100644 --- a/packages/cw20/src/logo.rs +++ b/packages/cw20/src/logo.rs @@ -1,8 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Binary; - - /// This is used for uploading logo data, or setting it in InstantiateData #[cw_serde] diff --git a/packages/cw20/src/msg.rs b/packages/cw20/src/msg.rs index 1d8087235..db807c2cf 100644 --- a/packages/cw20/src/msg.rs +++ b/packages/cw20/src/msg.rs @@ -1,6 +1,3 @@ - - - use crate::logo::Logo; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Binary, Uint128}; diff --git a/packages/cw20/src/receiver.rs b/packages/cw20/src/receiver.rs index d44cd78e6..630746e6a 100644 --- a/packages/cw20/src/receiver.rs +++ b/packages/cw20/src/receiver.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; diff --git a/packages/cw3/src/helpers.rs b/packages/cw3/src/helpers.rs index d2c08cc64..c360bab0f 100644 --- a/packages/cw3/src/helpers.rs +++ b/packages/cw3/src/helpers.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; diff --git a/packages/cw4/src/hook.rs b/packages/cw4/src/hook.rs index 80acac001..f3ce1bff2 100644 --- a/packages/cw4/src/hook.rs +++ b/packages/cw4/src/hook.rs @@ -1,6 +1,3 @@ - - - use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; diff --git a/packages/cw4/src/query.rs b/packages/cw4/src/query.rs index 337c30e59..6745d6af1 100644 --- a/packages/cw4/src/query.rs +++ b/packages/cw4/src/query.rs @@ -1,8 +1,5 @@ use cosmwasm_schema::cw_serde; - - - #[cw_serde] pub enum Cw4QueryMsg { From 73aee71dbd9dcb79869d61f3bbcbcc4744405ed1 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 18:13:20 +0200 Subject: [PATCH 427/631] Use the new #[cw_serde] macro for contracts --- contracts/cw1-subkeys/src/msg.rs | 19 ++++++----- contracts/cw1-subkeys/src/state.rs | 2 +- contracts/cw1-whitelist-ng/src/msg.rs | 15 ++++----- .../src/multitest/contract.rs | 8 ++--- contracts/cw1-whitelist-ng/src/state.rs | 2 +- contracts/cw1-whitelist/src/msg.rs | 13 ++++---- contracts/cw1-whitelist/src/state.rs | 2 +- contracts/cw1155-base/src/msg.rs | 5 ++- contracts/cw20-base/src/msg.rs | 8 ++--- contracts/cw20-base/src/state.rs | 9 ++---- contracts/cw20-ics20/src/amount.rs | 7 ++-- contracts/cw20-ics20/src/ibc.rs | 6 ++-- contracts/cw20-ics20/src/migrations.rs | 5 ++- contracts/cw20-ics20/src/msg.rs | 32 ++++++++----------- contracts/cw20-ics20/src/state.rs | 15 ++++----- contracts/cw3-fixed-multisig/src/msg.rs | 14 +++----- contracts/cw3-fixed-multisig/src/state.rs | 12 +++---- contracts/cw3-flex-multisig/src/msg.rs | 12 +++---- contracts/cw3-flex-multisig/src/state.rs | 8 ++--- contracts/cw4-group/src/helpers.rs | 5 ++- contracts/cw4-group/src/msg.rs | 13 +++----- contracts/cw4-stake/src/msg.rs | 16 ++++------ contracts/cw4-stake/src/state.rs | 6 ++-- 23 files changed, 96 insertions(+), 138 deletions(-) diff --git a/contracts/cw1-subkeys/src/msg.rs b/contracts/cw1-subkeys/src/msg.rs index 3af6943ef..deac3b30b 100644 --- a/contracts/cw1-subkeys/src/msg.rs +++ b/contracts/cw1-subkeys/src/msg.rs @@ -1,14 +1,14 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, CosmosMsg, Empty}; use cw_utils::{Expiration, NativeBalance}; use crate::state::Permissions; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -43,8 +43,7 @@ where }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -76,7 +75,7 @@ where }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct AllAllowancesResponse { pub allowances: Vec, } @@ -94,7 +93,7 @@ impl AllAllowancesResponse { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct AllowanceInfo { pub spender: String, pub balance: NativeBalance, @@ -114,7 +113,7 @@ impl AllowanceInfo { /// ``` /// # use cw_utils::{Expiration, NativeBalance}; /// # use cw1_subkeys::msg::AllowanceInfo; - /// # use cosmwasm_std::coin; + /// # use cosmwasm_schema::cw_serde;use cosmwasm_std::coin; /// /// let mut allows = vec![AllowanceInfo { /// spender: "spender2".to_owned(), @@ -143,7 +142,7 @@ impl AllowanceInfo { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct PermissionsInfo { pub spender: String, pub permissions: Permissions, @@ -183,7 +182,7 @@ impl PermissionsInfo { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct AllPermissionsResponse { pub permissions: Vec, } diff --git a/contracts/cw1-subkeys/src/state.rs b/contracts/cw1-subkeys/src/state.rs index 866e419eb..2b621ea4a 100644 --- a/contracts/cw1-subkeys/src/state.rs +++ b/contracts/cw1-subkeys/src/state.rs @@ -10,7 +10,7 @@ use cw_utils::{Expiration, NativeBalance}; // Could have implemented permissions for each cosmos module(StakingPermissions, GovPermissions etc...) // But that meant a lot of code for each module. Keeping the permissions inside one struct is more // optimal. Define other modules permissions here. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default, Copy)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default, Copy)] pub struct Permissions { pub delegate: bool, pub redelegate: bool, diff --git a/contracts/cw1-whitelist-ng/src/msg.rs b/contracts/cw1-whitelist-ng/src/msg.rs index 17fe069a5..9b8826caf 100644 --- a/contracts/cw1-whitelist-ng/src/msg.rs +++ b/contracts/cw1-whitelist-ng/src/msg.rs @@ -4,6 +4,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ to_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdError, }; @@ -31,8 +32,7 @@ impl InstantiateMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw1ExecMsg { /// Execute requests the contract to re-dispatch all these messages with the /// contract's address as sender. Every implementation has it's own logic to @@ -40,8 +40,7 @@ pub enum Cw1ExecMsg { Execute { msgs: Vec> }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum WhitelistExecMsg { /// Freeze will make a mutable contract immutable, must be called by an admin Freeze {}, @@ -89,8 +88,7 @@ impl WhitelistExecMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Cw1QueryMsg { /// Checks permissions of the caller on this proxy. /// If CanExecute returns true then a call to `Execute` with the same message, @@ -118,8 +116,7 @@ impl Cw1QueryMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum WhitelistQueryMsg { /// Shows all admins and whether or not it is mutable AdminList {}, @@ -145,7 +142,7 @@ impl WhitelistQueryMsg { } } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AdminListResponse { pub admins: Vec, pub mutable: bool, diff --git a/contracts/cw1-whitelist-ng/src/multitest/contract.rs b/contracts/cw1-whitelist-ng/src/multitest/contract.rs index 59a2063de..b14fcb354 100644 --- a/contracts/cw1-whitelist-ng/src/multitest/contract.rs +++ b/contracts/cw1-whitelist-ng/src/multitest/contract.rs @@ -54,7 +54,7 @@ where } } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] #[must_use] pub struct Cw1Executor<'a, App> { addr: Addr, @@ -87,7 +87,7 @@ impl<'a, App> Cw1Executor<'a, App> { } } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] #[must_use] pub struct WhitelistExecutor<'a, App> { addr: Addr, @@ -133,7 +133,7 @@ impl<'a, App> WhitelistExecutor<'a, App> { } } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] #[must_use] pub struct Instantiator<'a, App> { code_id: u64, @@ -185,7 +185,7 @@ impl<'a, App> Instantiator<'a, App> { } // Proxy for direct execution in multitest. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Cw1WhitelistProxy(Addr); impl Cw1WhitelistProxy { diff --git a/contracts/cw1-whitelist-ng/src/state.rs b/contracts/cw1-whitelist-ng/src/state.rs index af03b1529..336fdfdda 100644 --- a/contracts/cw1-whitelist-ng/src/state.rs +++ b/contracts/cw1-whitelist-ng/src/state.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{Addr, Empty}; use cw_storage_plus::Item; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] pub struct AdminList { pub admins: Vec, pub mutable: bool, diff --git a/contracts/cw1-whitelist/src/msg.rs b/contracts/cw1-whitelist/src/msg.rs index bdfb6d2f5..50dcf85d6 100644 --- a/contracts/cw1-whitelist/src/msg.rs +++ b/contracts/cw1-whitelist/src/msg.rs @@ -1,17 +1,17 @@ use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; + use std::fmt; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct InstantiateMsg { pub admins: Vec, pub mutable: bool, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -27,8 +27,7 @@ where UpdateAdmins { admins: Vec }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, @@ -41,7 +40,7 @@ where CanExecute { sender: String, msg: CosmosMsg }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AdminListResponse { pub admins: Vec, pub mutable: bool, diff --git a/contracts/cw1-whitelist/src/state.rs b/contracts/cw1-whitelist/src/state.rs index 9d3ec6d17..4b6f31ce5 100644 --- a/contracts/cw1-whitelist/src/state.rs +++ b/contracts/cw1-whitelist/src/state.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::Addr; use cw_storage_plus::Item; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] pub struct AdminList { pub admins: Vec, pub mutable: bool, diff --git a/contracts/cw1155-base/src/msg.rs b/contracts/cw1155-base/src/msg.rs index 4962c81c0..07e718d5b 100644 --- a/contracts/cw1155-base/src/msg.rs +++ b/contracts/cw1155-base/src/msg.rs @@ -1,7 +1,6 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct InstantiateMsg { /// The minter is the only one who can create new tokens. /// This is designed for a base token platform that is controlled by an external program or diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index 27f3a5b52..44ddc21fa 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -1,3 +1,4 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::{StdError, StdResult, Uint128}; use cw20::{Cw20Coin, Logo, MinterResponse}; use schemars::JsonSchema; @@ -5,7 +6,7 @@ use serde::{Deserialize, Serialize}; pub use cw20::Cw20ExecuteMsg as ExecuteMsg; -#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[cw_serde] pub struct InstantiateMarketingInfo { pub project: Option, pub description: Option, @@ -13,7 +14,7 @@ pub struct InstantiateMarketingInfo { pub logo: Option, } -#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[cw_serde] #[cfg_attr(test, derive(Default))] pub struct InstantiateMsg { pub name: String, @@ -69,8 +70,7 @@ impl InstantiateMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Returns the current balance of the given address, 0 if unset. /// Return type: BalanceResponse. diff --git a/contracts/cw20-base/src/state.rs b/contracts/cw20-base/src/state.rs index 5202b4911..dc02c6f19 100644 --- a/contracts/cw20-base/src/state.rs +++ b/contracts/cw20-base/src/state.rs @@ -1,13 +1,10 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; use cw_storage_plus::{Item, Map}; use cw20::{AllowanceResponse, Logo, MarketingInfoResponse}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct TokenInfo { pub name: String, pub symbol: String, @@ -16,7 +13,7 @@ pub struct TokenInfo { pub mint: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct MinterData { pub minter: Addr, /// cap is how many more tokens can be issued by the minter diff --git a/contracts/cw20-ics20/src/amount.rs b/contracts/cw20-ics20/src/amount.rs index f9e8dd532..a0c42d9f8 100644 --- a/contracts/cw20-ics20/src/amount.rs +++ b/contracts/cw20-ics20/src/amount.rs @@ -1,13 +1,10 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - use crate::error::ContractError; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Uint128}; use cw20::Cw20Coin; use std::convert::TryInto; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Amount { Native(Coin), // FIXME? USe Cw20CoinVerified, and validate cw20 addresses diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index f5f2dc213..74f77581c 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -1,6 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ attr, entry_point, from_binary, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, @@ -22,7 +23,7 @@ pub const ICS20_ORDERING: IbcOrder = IbcOrder::Unordered; /// The format for sending an ics20 packet. /// Proto defined here: https://github.com/cosmos/cosmos-sdk/blob/v0.42.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20 /// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] pub struct Ics20Packet { /// amount of tokens to transfer is encoded as a string, but limited to u64 max pub amount: Uint128, @@ -56,8 +57,7 @@ impl Ics20Packet { /// This is a generic ICS acknowledgement format. /// Proto defined here: https://github.com/cosmos/cosmos-sdk/blob/v0.42.0/proto/ibc/core/channel/v1/channel.proto#L141-L147 /// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Ics20Ack { Result(Binary), Error(String), diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index 8c67b6b49..3ff2fe09f 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -1,12 +1,11 @@ // v1 format is anything older than 0.12.0 pub mod v1 { - use schemars::JsonSchema; - use serde::{Deserialize, Serialize}; + use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; use cw_storage_plus::Item; - #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] + #[cw_serde] pub struct Config { pub default_timeout: u64, pub gov_contract: Addr, diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index 6cb68ccbe..d9879802e 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -1,12 +1,10 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cw20::Cw20ReceiveMsg; use crate::amount::Amount; use crate::state::ChannelInfo; -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[cw_serde] pub struct InitMsg { /// Default timeout for ics20 packets, specified in seconds pub default_timeout: u64, @@ -19,19 +17,18 @@ pub struct InitMsg { pub default_gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct AllowMsg { pub contract: String, pub gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[cw_serde] pub struct MigrateMsg { pub default_gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { /// This accepts a properly-encoded ReceiveMsg from a cw20 contract Receive(Cw20ReceiveMsg), @@ -44,7 +41,7 @@ pub enum ExecuteMsg { } /// This is the message we accept via Receive -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct TransferMsg { /// The local channel to send the packets on pub channel: String, @@ -56,8 +53,7 @@ pub struct TransferMsg { pub timeout: Option, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Return the port ID bound by this contract. Returns PortResponse Port {}, @@ -79,12 +75,12 @@ pub enum QueryMsg { }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ListChannelsResponse { pub channels: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ChannelResponse { /// Information on the channel's connection pub info: ChannelInfo, @@ -95,30 +91,30 @@ pub struct ChannelResponse { pub total_sent: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct PortResponse { pub port_id: String, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ConfigResponse { pub default_timeout: u64, pub default_gas_limit: Option, pub gov_contract: String, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AllowedResponse { pub is_allowed: bool, pub gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ListAllowedResponse { pub allow: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AllowedInfo { pub contract: String, pub gas_limit: Option, diff --git a/contracts/cw20-ics20/src/state.rs b/contracts/cw20-ics20/src/state.rs index 57cbe0a0a..19e05a482 100644 --- a/contracts/cw20-ics20/src/state.rs +++ b/contracts/cw20-ics20/src/state.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, IbcEndpoint, StdResult, Storage, Uint128}; use cw_controllers::Admin; use cw_storage_plus::{Item, Map}; @@ -23,19 +21,20 @@ pub const CHANNEL_STATE: Map<(&str, &str), ChannelState> = Map::new("channel_sta /// Every cw20 contract we allow to be sent is stored here, possibly with a gas_limit pub const ALLOW_LIST: Map<&Addr, AllowInfo> = Map::new("allow_list"); -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +#[cw_serde] +#[derive(Default)] pub struct ChannelState { pub outstanding: Uint128, pub total_sent: Uint128, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Config { pub default_timeout: u64, pub default_gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ChannelInfo { /// id of this channel pub id: String, @@ -45,12 +44,12 @@ pub struct ChannelInfo { pub connection_id: String, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct AllowInfo { pub gas_limit: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct ReplyArgs { pub channel: String, pub denom: String, diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index 18ed4eedd..3aaa37811 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -1,26 +1,23 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; use cw_utils::{Duration, Expiration, Threshold}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct InstantiateMsg { pub voters: Vec, pub threshold: Threshold, pub max_voting_period: Duration, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Voter { pub addr: String, pub weight: u64, } // TODO: add some T variants? Maybe good enough as fixed Empty for now -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Propose { title: String, @@ -42,8 +39,7 @@ pub enum ExecuteMsg { } // We can also add this as a cw3 extension -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Return ThresholdResponse Threshold {}, diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index 11d49daf1..d0c7914b8 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; use cw3::{Status, Vote}; @@ -11,14 +9,14 @@ use cw_utils::{Duration, Expiration, Threshold}; // Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" const PRECISION_FACTOR: u128 = 1_000_000_000; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Config { pub threshold: Threshold, pub total_weight: u64, pub max_voting_period: Duration, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Proposal { pub title: String, pub description: String, @@ -126,7 +124,7 @@ impl Proposal { } // weight of votes for each option -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Votes { pub yes: u64, pub no: u64, @@ -170,7 +168,7 @@ fn votes_needed(weight: u64, percentage: Decimal) -> u64 { // we cast a ballot with our chosen vote and a given weight // stored under the key that voted -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Ballot { pub weight: u64, pub vote: Vote, diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 99437b26b..0d77b2dea 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{CosmosMsg, Empty}; use cw3::Vote; use cw4::MemberChangedHookMsg; @@ -8,7 +6,7 @@ use cw_utils::{Duration, Expiration, Threshold}; use crate::state::Executor; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct InstantiateMsg { // this is the group contract that contains the member list pub group_addr: String, @@ -20,8 +18,7 @@ pub struct InstantiateMsg { } // TODO: add some T variants? Maybe good enough as fixed Empty for now -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Propose { title: String, @@ -45,8 +42,7 @@ pub enum ExecuteMsg { } // We can also add this as a cw3 extension -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Return ThresholdResponse Threshold {}, diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index a1e388777..e6dc06bd8 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, QuerierWrapper}; use cw4::Cw4Contract; use cw_storage_plus::Item; @@ -9,7 +7,7 @@ use cw_utils::{Duration, Threshold}; use crate::error::ContractError; /// Defines who is able to execute proposals once passed -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub enum Executor { /// Any member of the voting group, even with 0 points Member, @@ -17,7 +15,7 @@ pub enum Executor { Only(Addr), } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Config { pub threshold: Threshold, pub max_voting_period: Duration, diff --git a/contracts/cw4-group/src/helpers.rs b/contracts/cw4-group/src/helpers.rs index add7451a4..b7719d90b 100644 --- a/contracts/cw4-group/src/helpers.rs +++ b/contracts/cw4-group/src/helpers.rs @@ -1,7 +1,6 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::ops::Deref; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use cw4::{Cw4Contract, Member}; @@ -11,7 +10,7 @@ use crate::msg::ExecuteMsg; /// for working with cw4-group contracts. /// /// It extends Cw4Contract to add the extra calls from cw4-group. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw4GroupContract(pub Cw4Contract); impl Deref for Cw4GroupContract { diff --git a/contracts/cw4-group/src/msg.rs b/contracts/cw4-group/src/msg.rs index e1759ac54..332dab8b7 100644 --- a/contracts/cw4-group/src/msg.rs +++ b/contracts/cw4-group/src/msg.rs @@ -1,10 +1,7 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cw4::Member; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct InstantiateMsg { /// The admin is the only account that can update the group state. /// Omit it to make the group immutable. @@ -12,8 +9,7 @@ pub struct InstantiateMsg { pub members: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { /// Change the admin UpdateAdmin { admin: Option }, @@ -29,8 +25,7 @@ pub enum ExecuteMsg { RemoveHook { addr: String }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Return AdminResponse Admin {}, diff --git a/contracts/cw4-stake/src/msg.rs b/contracts/cw4-stake/src/msg.rs index 29e81f595..39f4bc273 100644 --- a/contracts/cw4-stake/src/msg.rs +++ b/contracts/cw4-stake/src/msg.rs @@ -1,12 +1,11 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::Uint128; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use cw20::{Cw20ReceiveMsg, Denom}; pub use cw_controllers::ClaimsResponse; use cw_utils::Duration; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct InstantiateMsg { /// denom of the token to stake pub denom: Denom, @@ -18,8 +17,7 @@ pub struct InstantiateMsg { pub admin: Option, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { /// Bond will bond all staking tokens sent with the message and update membership weight Bond {}, @@ -42,15 +40,13 @@ pub enum ExecuteMsg { Receive(Cw20ReceiveMsg), } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ReceiveMsg { /// Only valid cw20 message is to bond the tokens Bond {}, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum QueryMsg { /// Claims shows the tokens in process of unbonding for this address Claims { @@ -79,7 +75,7 @@ pub enum QueryMsg { Hooks {}, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct StakedResponse { pub stake: Uint128, pub denom: Denom, diff --git a/contracts/cw4-stake/src/state.rs b/contracts/cw4-stake/src/state.rs index d8c69f98b..b27f969eb 100644 --- a/contracts/cw4-stake/src/state.rs +++ b/contracts/cw4-stake/src/state.rs @@ -1,6 +1,4 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; use cw20::Denom; use cw4::TOTAL_KEY; @@ -10,7 +8,7 @@ use cw_utils::Duration; pub const CLAIMS: Claims = Claims::new("claims"); -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[cw_serde] pub struct Config { /// denom of the token to stake pub denom: Denom, From 97050ee1ee84eeda8777ac508cdd6cc4ae7ed618 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 23:17:34 +0200 Subject: [PATCH 428/631] Annotate contract queries with return types --- contracts/cw1-subkeys/src/msg.rs | 17 +++++++++------- contracts/cw1-whitelist/src/msg.rs | 5 ++++- contracts/cw20-base/src/msg.rs | 27 +++++++++++++++---------- contracts/cw20-ics20/src/msg.rs | 23 +++++++++++++-------- contracts/cw3-fixed-multisig/src/msg.rs | 26 ++++++++++++++---------- contracts/cw3-flex-multisig/src/msg.rs | 26 ++++++++++++++---------- contracts/cw4-group/src/msg.rs | 17 +++++++++------- contracts/cw4-stake/src/msg.rs | 27 +++++++++++++------------ packages/controllers/src/lib.rs | 2 +- packages/cw1155/src/query.rs | 18 ++++++++--------- 10 files changed, 109 insertions(+), 79 deletions(-) diff --git a/contracts/cw1-subkeys/src/msg.rs b/contracts/cw1-subkeys/src/msg.rs index deac3b30b..ba9e71f4b 100644 --- a/contracts/cw1-subkeys/src/msg.rs +++ b/contracts/cw1-subkeys/src/msg.rs @@ -2,8 +2,9 @@ use schemars::JsonSchema; use std::fmt; -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Coin, CosmosMsg, Empty}; +use cw1::CanExecuteResponse; use cw_utils::{Expiration, NativeBalance}; use crate::state::Permissions; @@ -44,31 +45,33 @@ where } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, { /// Shows all admins and whether or not it is mutable - /// Returns cw1-whitelist::AdminListResponse + #[returns(cw1_whitelist::msg::AdminListResponse)] AdminList {}, /// Get the current allowance for the given subkey (how much it can spend) - /// Returns crate::state::Allowance + #[returns(crate::state::Allowance)] Allowance { spender: String }, /// Get the current permissions for the given subkey (how much it can spend) - /// Returns PermissionsInfo + #[returns(PermissionsInfo)] Permissions { spender: String }, /// Checks permissions of the caller on this proxy. /// If CanExecute returns true then a call to `Execute` with the same message, /// before any further state changes, should also succeed. + #[returns(CanExecuteResponse)] CanExecute { sender: String, msg: CosmosMsg }, /// Gets all Allowances for this contract - /// Returns AllAllowancesResponse + #[returns(AllAllowancesResponse)] AllAllowances { start_after: Option, limit: Option, }, /// Gets all Permissions for this contract - /// Returns AllPermissionsResponse + #[returns(AllPermissionsResponse)] AllPermissions { start_after: Option, limit: Option, @@ -113,7 +116,7 @@ impl AllowanceInfo { /// ``` /// # use cw_utils::{Expiration, NativeBalance}; /// # use cw1_subkeys::msg::AllowanceInfo; - /// # use cosmwasm_schema::cw_serde;use cosmwasm_std::coin; + /// # use cosmwasm_schema::{cw_serde, QueryResponses};use cosmwasm_std::coin; /// /// let mut allows = vec![AllowanceInfo { /// spender: "spender2".to_owned(), diff --git a/contracts/cw1-whitelist/src/msg.rs b/contracts/cw1-whitelist/src/msg.rs index 50dcf85d6..16d7537b4 100644 --- a/contracts/cw1-whitelist/src/msg.rs +++ b/contracts/cw1-whitelist/src/msg.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use std::fmt; -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; #[cw_serde] @@ -28,15 +28,18 @@ where } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg where T: Clone + fmt::Debug + PartialEq + JsonSchema, { /// Shows all admins and whether or not it is mutable + #[returns(AdminListResponse)] AdminList {}, /// Checks permissions of the caller on this proxy. /// If CanExecute returns true then a call to `Execute` with the same message, /// before any further state changes, should also succeed. + #[returns(cw1::CanExecuteResponse)] CanExecute { sender: String, msg: CosmosMsg }, } diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index 44ddc21fa..20b315eaf 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -1,6 +1,10 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{StdError, StdResult, Uint128}; -use cw20::{Cw20Coin, Logo, MinterResponse}; +use cw20::{ + AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceResponse, + BalanceResponse, Cw20Coin, DownloadLogoResponse, Logo, MarketingInfoResponse, MinterResponse, + TokenInfoResponse, +}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -71,24 +75,25 @@ impl InstantiateMsg { } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { /// Returns the current balance of the given address, 0 if unset. - /// Return type: BalanceResponse. + #[returns(BalanceResponse)] Balance { address: String }, /// Returns metadata on the contract - name, decimals, supply, etc. - /// Return type: TokenInfoResponse. + #[returns(TokenInfoResponse)] TokenInfo {}, /// Only with "mintable" extension. /// Returns who can mint and the hard cap on maximum tokens after minting. - /// Return type: MinterResponse. + #[returns(MinterResponse)] Minter {}, /// Only with "allowance" extension. /// Returns how much spender can use from owner account, 0 if unset. - /// Return type: AllowanceResponse. + #[returns(AllowanceResponse)] Allowance { owner: String, spender: String }, /// Only with "enumerable" extension (and "allowances") /// Returns all allowances this owner has approved. Supports pagination. - /// Return type: AllAllowancesResponse. + #[returns(AllAllowancesResponse)] AllAllowances { owner: String, start_after: Option, @@ -96,7 +101,7 @@ pub enum QueryMsg { }, /// Only with "enumerable" extension (and "allowances") /// Returns all allowances this spender has been granted. Supports pagination. - /// Return type: AllSpenderAllowancesResponse. + #[returns(AllSpenderAllowancesResponse)] AllSpenderAllowances { spender: String, start_after: Option, @@ -104,7 +109,7 @@ pub enum QueryMsg { }, /// Only with "enumerable" extension /// Returns all accounts that have balances. Supports pagination. - /// Return type: AllAccountsResponse. + #[returns(AllAccountsResponse)] AllAccounts { start_after: Option, limit: Option, @@ -112,12 +117,12 @@ pub enum QueryMsg { /// Only with "marketing" extension /// Returns more metadata on the contract to display in the client: /// - description, logo, project url, etc. - /// Return type: MarketingInfoResponse + #[returns(MarketingInfoResponse)] MarketingInfo {}, /// Only with "marketing" extension /// Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this /// contract. - /// Return type: DownloadLogoResponse. + #[returns(DownloadLogoResponse)] DownloadLogo {}, } diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index d9879802e..b0cad95cc 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -1,5 +1,6 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cw20::Cw20ReceiveMsg; +use cw_controllers::AdminResponse; use crate::amount::Amount; use crate::state::ChannelInfo; @@ -54,21 +55,27 @@ pub struct TransferMsg { } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return the port ID bound by this contract. Returns PortResponse + /// Return the port ID bound by this contract. + #[returns(PortResponse)] Port {}, - /// Show all channels we have connected to. Return type is ListChannelsResponse. + /// Show all channels we have connected to. + #[returns(ListChannelsResponse)] ListChannels {}, /// Returns the details of the name channel, error if not created. - /// Return type: ChannelResponse. + #[returns(ChannelResponse)] Channel { id: String }, - /// Show the Config. Returns ConfigResponse (currently including admin as well) + /// Show the Config. + #[returns(ConfigResponse)] Config {}, - /// Return AdminResponse + #[returns(AdminResponse)] Admin {}, - /// Query if a given cw20 contract is allowed. Returns AllowedResponse + /// Query if a given cw20 contract is allowed. + #[returns(AllowedResponse)] Allowed { contract: String }, - /// List all allowed cw20 contracts. Returns ListAllowedResponse + /// List all allowed cw20 contracts. + #[returns(ListAllowedResponse)] ListAllowed { start_after: Option, limit: Option, diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index 3aaa37811..ea40680c6 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -1,7 +1,10 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::Vote; -use cw_utils::{Duration, Expiration, Threshold}; +use cw3::{ + ProposalListResponse, ProposalResponse, Vote, VoteListResponse, VoteResponse, + VoterListResponse, VoterResponse, +}; +use cw_utils::{Duration, Expiration, Threshold, ThresholdResponse}; #[cw_serde] pub struct InstantiateMsg { @@ -40,32 +43,33 @@ pub enum ExecuteMsg { // We can also add this as a cw3 extension #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return ThresholdResponse + #[returns(ThresholdResponse)] Threshold {}, - /// Returns ProposalResponse + #[returns(ProposalResponse)] Proposal { proposal_id: u64 }, - /// Returns ProposalListResponse + #[returns(ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - /// Returns ProposalListResponse + #[returns(ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - /// Returns VoteResponse + #[returns(VoteResponse)] Vote { proposal_id: u64, voter: String }, - /// Returns VoteListResponse + #[returns(VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - /// Returns VoterInfo + #[returns(VoterResponse)] Voter { address: String }, - /// Returns VoterListResponse + #[returns(VoterListResponse)] ListVoters { start_after: Option, limit: Option, diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 0d77b2dea..13a8ac52e 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -1,8 +1,11 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::Vote; +use cw3::{ + ProposalListResponse, ProposalResponse, Vote, VoteListResponse, VoteResponse, + VoterListResponse, VoterResponse, +}; use cw4::MemberChangedHookMsg; -use cw_utils::{Duration, Expiration, Threshold}; +use cw_utils::{Duration, Expiration, Threshold, ThresholdResponse}; use crate::state::Executor; @@ -43,32 +46,33 @@ pub enum ExecuteMsg { // We can also add this as a cw3 extension #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return ThresholdResponse + #[returns(ThresholdResponse)] Threshold {}, - /// Returns ProposalResponse + #[returns(ProposalResponse)] Proposal { proposal_id: u64 }, - /// Returns ProposalListResponse + #[returns(ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - /// Returns ProposalListResponse + #[returns(ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - /// Returns VoteResponse + #[returns(VoteResponse)] Vote { proposal_id: u64, voter: String }, - /// Returns VoteListResponse + #[returns(VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - /// Returns VoterInfo + #[returns(VoterResponse)] Voter { address: String }, - /// Returns VoterListResponse + #[returns(VoterListResponse)] ListVoters { start_after: Option, limit: Option, diff --git a/contracts/cw4-group/src/msg.rs b/contracts/cw4-group/src/msg.rs index 332dab8b7..dd751a948 100644 --- a/contracts/cw4-group/src/msg.rs +++ b/contracts/cw4-group/src/msg.rs @@ -1,5 +1,6 @@ -use cosmwasm_schema::cw_serde; -use cw4::Member; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cw4::{Member, MemberListResponse, MemberResponse, TotalWeightResponse}; +use cw_controllers::{AdminResponse, HooksResponse}; #[cw_serde] pub struct InstantiateMsg { @@ -26,21 +27,23 @@ pub enum ExecuteMsg { } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return AdminResponse + #[returns(AdminResponse)] Admin {}, - /// Return TotalWeightResponse + #[returns(TotalWeightResponse)] TotalWeight {}, - /// Returns MembersListResponse + #[returns(MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - /// Returns MemberResponse + #[returns(MemberResponse)] Member { addr: String, at_height: Option, }, - /// Shows all registered hooks. Returns HooksResponse. + /// Shows all registered hooks. + #[returns(HooksResponse)] Hooks {}, } diff --git a/contracts/cw4-stake/src/msg.rs b/contracts/cw4-stake/src/msg.rs index 39f4bc273..04c1423db 100644 --- a/contracts/cw4-stake/src/msg.rs +++ b/contracts/cw4-stake/src/msg.rs @@ -1,8 +1,9 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; use cw20::{Cw20ReceiveMsg, Denom}; -pub use cw_controllers::ClaimsResponse; +use cw4::{MemberListResponse, MemberResponse, TotalWeightResponse}; +pub use cw_controllers::{AdminResponse, ClaimsResponse, HooksResponse}; use cw_utils::Duration; #[cw_serde] @@ -47,31 +48,31 @@ pub enum ReceiveMsg { } #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { /// Claims shows the tokens in process of unbonding for this address - Claims { - address: String, - }, + #[returns(ClaimsResponse)] + Claims { address: String }, // Show the number of tokens currently staked by this address. - Staked { - address: String, - }, + #[returns(StakedResponse)] + Staked { address: String }, - /// Return AdminResponse + #[returns(AdminResponse)] Admin {}, - /// Return TotalWeightResponse + #[returns(TotalWeightResponse)] TotalWeight {}, - /// Returns MembersListResponse + #[returns(MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - /// Returns MemberResponse + #[returns(MemberResponse)] Member { addr: String, at_height: Option, }, - /// Shows all registered hooks. Returns HooksResponse. + /// Shows all registered hooks. + #[returns(HooksResponse)] Hooks {}, } diff --git a/packages/controllers/src/lib.rs b/packages/controllers/src/lib.rs index 303cf6a44..eb767b74f 100644 --- a/packages/controllers/src/lib.rs +++ b/packages/controllers/src/lib.rs @@ -4,4 +4,4 @@ mod hooks; pub use admin::{Admin, AdminError, AdminResponse}; pub use claim::{Claim, Claims, ClaimsResponse}; -pub use hooks::{HookError, Hooks}; +pub use hooks::{HookError, Hooks, HooksResponse}; diff --git a/packages/cw1155/src/query.rs b/packages/cw1155/src/query.rs index 12cdb99f2..b20076911 100644 --- a/packages/cw1155/src/query.rs +++ b/packages/cw1155/src/query.rs @@ -1,23 +1,23 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; use cw_utils::Expiration; use crate::msg::TokenId; #[cw_serde] - +#[derive(QueryResponses)] pub enum Cw1155QueryMsg { /// Returns the current balance of the given address, 0 if unset. - /// Return type: BalanceResponse. + #[returns(BalanceResponse)] Balance { owner: String, token_id: TokenId }, /// Returns the current balance of the given address for a batch of tokens, 0 if unset. - /// Return type: BatchBalanceResponse. + #[returns(BatchBalanceResponse)] BatchBalance { owner: String, token_ids: Vec, }, /// List all operators that can access all of the owner's tokens. - /// Return type: ApprovedForAllResponse. + #[returns(ApprovedForAllResponse)] ApprovedForAll { owner: String, /// unset or false will filter out expired approvals, you must set to true to see them @@ -26,17 +26,17 @@ pub enum Cw1155QueryMsg { limit: Option, }, /// Query approved status `owner` granted to `operator`. - /// Return type: IsApprovedForAllResponse + #[returns(IsApprovedForAllResponse)] IsApprovedForAll { owner: String, operator: String }, /// With MetaData Extension. /// Query metadata of token - /// Return type: TokenInfoResponse. + #[returns(TokenInfoResponse)] TokenInfo { token_id: TokenId }, /// With Enumerable extension. /// Returns all tokens owned by the given address, [] if unset. - /// Return type: TokensResponse. + #[returns(TokensResponse)] Tokens { owner: String, start_after: Option, @@ -44,7 +44,7 @@ pub enum Cw1155QueryMsg { }, /// With Enumerable extension. /// Requires pagination. Lists all token_ids controlled by the contract. - /// Return type: TokensResponse. + #[returns(TokensResponse)] AllTokens { start_after: Option, limit: Option, From 6c8fbb100b30cebd838e7464dd225492ef3334bd Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 23:28:29 +0200 Subject: [PATCH 429/631] Use new schema generation API --- contracts/cw1-subkeys/src/bin/schema.rs | 25 +++++---------- contracts/cw1-whitelist/src/bin/schema.rs | 21 ++++-------- contracts/cw1155-base/src/bin/schema.rs | 32 ++++--------------- contracts/cw20-base/src/bin/schema.rs | 28 ++++------------ contracts/cw20-ics20/src/bin/schema.rs | 26 ++++----------- .../cw3-fixed-multisig/src/bin/schema.rs | 18 ++++------- contracts/cw3-flex-multisig/src/bin/schema.rs | 18 ++++------- contracts/cw4-group/src/bin/schema.rs | 22 ++++--------- contracts/cw4-stake/src/bin/schema.rs | 26 ++++----------- 9 files changed, 59 insertions(+), 157 deletions(-) diff --git a/contracts/cw1-subkeys/src/bin/schema.rs b/contracts/cw1-subkeys/src/bin/schema.rs index aba98a7fd..1616b5f58 100644 --- a/contracts/cw1-subkeys/src/bin/schema.rs +++ b/contracts/cw1-subkeys/src/bin/schema.rs @@ -1,22 +1,13 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use cosmwasm_schema::write_api; -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; +use cw1_subkeys::msg::{ExecuteMsg, QueryMsg}; -use cw1_subkeys::msg::{AllAllowancesResponse, ExecuteMsg, QueryMsg}; -use cw1_subkeys::state::Allowance; -use cw1_whitelist::msg::{AdminListResponse, InstantiateMsg}; +use cw1_whitelist::msg::InstantiateMsg; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema_with_title(&schema_for!(QueryMsg), &out_dir, "QueryMsg"); - export_schema(&schema_for!(Allowance), &out_dir); - export_schema(&schema_for!(AdminListResponse), &out_dir); - export_schema(&schema_for!(AllAllowancesResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw1-whitelist/src/bin/schema.rs b/contracts/cw1-whitelist/src/bin/schema.rs index 59dde62cc..e72e54623 100644 --- a/contracts/cw1-whitelist/src/bin/schema.rs +++ b/contracts/cw1-whitelist/src/bin/schema.rs @@ -1,18 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use cosmwasm_schema::write_api; -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; - -use cw1_whitelist::msg::{AdminListResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; +use cw1_whitelist::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema_with_title(&schema_for!(QueryMsg), &out_dir, "QueryMsg"); - export_schema(&schema_for!(AdminListResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw1155-base/src/bin/schema.rs b/contracts/cw1155-base/src/bin/schema.rs index 3fc9e8d63..a4c4d13d2 100644 --- a/contracts/cw1155-base/src/bin/schema.rs +++ b/contracts/cw1155-base/src/bin/schema.rs @@ -1,30 +1,12 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use cosmwasm_schema::write_api; -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw1155::{ - ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, Cw1155BatchReceiveMsg, - Cw1155ExecuteMsg, Cw1155QueryMsg, Cw1155ReceiveMsg, IsApprovedForAllResponse, - TokenInfoResponse, TokensResponse, -}; +use cw1155::{Cw1155ExecuteMsg, Cw1155QueryMsg}; use cw1155_base::msg::InstantiateMsg; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(Cw1155ExecuteMsg), &out_dir); - export_schema(&schema_for!(Cw1155QueryMsg), &out_dir); - export_schema(&schema_for!(Cw1155ReceiveMsg), &out_dir); - export_schema(&schema_for!(Cw1155BatchReceiveMsg), &out_dir); - export_schema(&schema_for!(BalanceResponse), &out_dir); - export_schema(&schema_for!(BatchBalanceResponse), &out_dir); - export_schema(&schema_for!(ApprovedForAllResponse), &out_dir); - export_schema(&schema_for!(IsApprovedForAllResponse), &out_dir); - export_schema(&schema_for!(TokenInfoResponse), &out_dir); - export_schema(&schema_for!(TokensResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: Cw1155ExecuteMsg, + query: Cw1155QueryMsg, + } } diff --git a/contracts/cw20-base/src/bin/schema.rs b/contracts/cw20-base/src/bin/schema.rs index e715901a6..40d16fd4f 100644 --- a/contracts/cw20-base/src/bin/schema.rs +++ b/contracts/cw20-base/src/bin/schema.rs @@ -1,27 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use cosmwasm_schema::write_api; -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20::{ - AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceResponse, - BalanceResponse, TokenInfoResponse, -}; use cw20_base::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(AllowanceResponse), &out_dir); - export_schema(&schema_for!(BalanceResponse), &out_dir); - export_schema(&schema_for!(TokenInfoResponse), &out_dir); - export_schema(&schema_for!(AllAllowancesResponse), &out_dir); - export_schema(&schema_for!(AllSpenderAllowancesResponse), &out_dir); - export_schema(&schema_for!(AllAccountsResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw20-ics20/src/bin/schema.rs b/contracts/cw20-ics20/src/bin/schema.rs index fb3b116a2..55c982ad0 100644 --- a/contracts/cw20-ics20/src/bin/schema.rs +++ b/contracts/cw20-ics20/src/bin/schema.rs @@ -1,23 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use cosmwasm_schema::write_api; -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use cw20_ics20::msg::{ - ChannelResponse, ExecuteMsg, InitMsg, ListChannelsResponse, PortResponse, QueryMsg, TransferMsg, -}; +use cw20_ics20::msg::{ExecuteMsg, InitMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InitMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(TransferMsg), &out_dir); - export_schema(&schema_for!(ChannelResponse), &out_dir); - export_schema(&schema_for!(ListChannelsResponse), &out_dir); - export_schema(&schema_for!(PortResponse), &out_dir); + write_api! { + instantiate: InitMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw3-fixed-multisig/src/bin/schema.rs b/contracts/cw3-fixed-multisig/src/bin/schema.rs index acbce1f87..80810258f 100644 --- a/contracts/cw3-fixed-multisig/src/bin/schema.rs +++ b/contracts/cw3-fixed-multisig/src/bin/schema.rs @@ -1,17 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; +use cosmwasm_schema::write_api; use cw3_fixed_multisig::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema_with_title(&schema_for!(QueryMsg), &out_dir, "QueryMsg"); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw3-flex-multisig/src/bin/schema.rs b/contracts/cw3-flex-multisig/src/bin/schema.rs index dd4e52de2..e14159759 100644 --- a/contracts/cw3-flex-multisig/src/bin/schema.rs +++ b/contracts/cw3-flex-multisig/src/bin/schema.rs @@ -1,17 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; +use cosmwasm_schema::write_api; use cw3_flex_multisig::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema_with_title(&schema_for!(QueryMsg), &out_dir, "QueryMsg"); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw4-group/src/bin/schema.rs b/contracts/cw4-group/src/bin/schema.rs index 01cdd1675..20fdf9b16 100644 --- a/contracts/cw4-group/src/bin/schema.rs +++ b/contracts/cw4-group/src/bin/schema.rs @@ -1,22 +1,12 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; +use cosmwasm_schema::write_api; pub use cw4::{AdminResponse, MemberListResponse, MemberResponse, TotalWeightResponse}; pub use cw4_group::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema_with_title(&schema_for!(InstantiateMsg), &out_dir, "InstantiateMsg"); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema_with_title(&schema_for!(QueryMsg), &out_dir, "QueryMsg"); - export_schema(&schema_for!(AdminResponse), &out_dir); - export_schema(&schema_for!(MemberListResponse), &out_dir); - export_schema(&schema_for!(MemberResponse), &out_dir); - export_schema(&schema_for!(TotalWeightResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } diff --git a/contracts/cw4-stake/src/bin/schema.rs b/contracts/cw4-stake/src/bin/schema.rs index 891f94d7a..b6d3f29ba 100644 --- a/contracts/cw4-stake/src/bin/schema.rs +++ b/contracts/cw4-stake/src/bin/schema.rs @@ -1,7 +1,4 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; +use cosmwasm_schema::write_api; pub use cw4::{AdminResponse, MemberListResponse, MemberResponse, TotalWeightResponse}; pub use cw4_stake::msg::{ @@ -9,20 +6,9 @@ pub use cw4_stake::msg::{ }; fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(ReceiveMsg), &out_dir); - - export_schema(&schema_for!(AdminResponse), &out_dir); - export_schema(&schema_for!(MemberListResponse), &out_dir); - export_schema(&schema_for!(MemberResponse), &out_dir); - export_schema(&schema_for!(TotalWeightResponse), &out_dir); - export_schema(&schema_for!(ClaimsResponse), &out_dir); - export_schema(&schema_for!(StakedResponse), &out_dir); + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } } From 62773eda992f5aff9968abeb965e4a56163c0487 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 30 Aug 2022 23:39:54 +0200 Subject: [PATCH 430/631] lints --- contracts/cw1-subkeys/src/msg.rs | 3 +-- contracts/cw20-base/src/msg.rs | 24 ++++++++++-------------- contracts/cw20-ics20/src/msg.rs | 3 +-- contracts/cw3-fixed-multisig/src/msg.rs | 23 ++++++++++------------- contracts/cw3-flex-multisig/src/msg.rs | 23 ++++++++++------------- contracts/cw4-group/src/msg.rs | 13 ++++++------- contracts/cw4-stake/src/msg.rs | 15 +++++++-------- 7 files changed, 45 insertions(+), 59 deletions(-) diff --git a/contracts/cw1-subkeys/src/msg.rs b/contracts/cw1-subkeys/src/msg.rs index ba9e71f4b..a3f17a0cf 100644 --- a/contracts/cw1-subkeys/src/msg.rs +++ b/contracts/cw1-subkeys/src/msg.rs @@ -4,7 +4,6 @@ use std::fmt; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Coin, CosmosMsg, Empty}; -use cw1::CanExecuteResponse; use cw_utils::{Expiration, NativeBalance}; use crate::state::Permissions; @@ -62,7 +61,7 @@ where /// Checks permissions of the caller on this proxy. /// If CanExecute returns true then a call to `Execute` with the same message, /// before any further state changes, should also succeed. - #[returns(CanExecuteResponse)] + #[returns(cw1::CanExecuteResponse)] CanExecute { sender: String, msg: CosmosMsg }, /// Gets all Allowances for this contract #[returns(AllAllowancesResponse)] diff --git a/contracts/cw20-base/src/msg.rs b/contracts/cw20-base/src/msg.rs index 20b315eaf..208871255 100644 --- a/contracts/cw20-base/src/msg.rs +++ b/contracts/cw20-base/src/msg.rs @@ -1,10 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{StdError, StdResult, Uint128}; -use cw20::{ - AllAccountsResponse, AllAllowancesResponse, AllSpenderAllowancesResponse, AllowanceResponse, - BalanceResponse, Cw20Coin, DownloadLogoResponse, Logo, MarketingInfoResponse, MinterResponse, - TokenInfoResponse, -}; +use cw20::{Cw20Coin, Logo, MinterResponse}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -78,22 +74,22 @@ impl InstantiateMsg { #[derive(QueryResponses)] pub enum QueryMsg { /// Returns the current balance of the given address, 0 if unset. - #[returns(BalanceResponse)] + #[returns(cw20::BalanceResponse)] Balance { address: String }, /// Returns metadata on the contract - name, decimals, supply, etc. - #[returns(TokenInfoResponse)] + #[returns(cw20::TokenInfoResponse)] TokenInfo {}, /// Only with "mintable" extension. /// Returns who can mint and the hard cap on maximum tokens after minting. - #[returns(MinterResponse)] + #[returns(cw20::MinterResponse)] Minter {}, /// Only with "allowance" extension. /// Returns how much spender can use from owner account, 0 if unset. - #[returns(AllowanceResponse)] + #[returns(cw20::AllowanceResponse)] Allowance { owner: String, spender: String }, /// Only with "enumerable" extension (and "allowances") /// Returns all allowances this owner has approved. Supports pagination. - #[returns(AllAllowancesResponse)] + #[returns(cw20::AllAllowancesResponse)] AllAllowances { owner: String, start_after: Option, @@ -101,7 +97,7 @@ pub enum QueryMsg { }, /// Only with "enumerable" extension (and "allowances") /// Returns all allowances this spender has been granted. Supports pagination. - #[returns(AllSpenderAllowancesResponse)] + #[returns(cw20::AllSpenderAllowancesResponse)] AllSpenderAllowances { spender: String, start_after: Option, @@ -109,7 +105,7 @@ pub enum QueryMsg { }, /// Only with "enumerable" extension /// Returns all accounts that have balances. Supports pagination. - #[returns(AllAccountsResponse)] + #[returns(cw20::AllAccountsResponse)] AllAccounts { start_after: Option, limit: Option, @@ -117,12 +113,12 @@ pub enum QueryMsg { /// Only with "marketing" extension /// Returns more metadata on the contract to display in the client: /// - description, logo, project url, etc. - #[returns(MarketingInfoResponse)] + #[returns(cw20::MarketingInfoResponse)] MarketingInfo {}, /// Only with "marketing" extension /// Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this /// contract. - #[returns(DownloadLogoResponse)] + #[returns(cw20::DownloadLogoResponse)] DownloadLogo {}, } diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index b0cad95cc..c137a8149 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -1,6 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cw20::Cw20ReceiveMsg; -use cw_controllers::AdminResponse; use crate::amount::Amount; use crate::state::ChannelInfo; @@ -69,7 +68,7 @@ pub enum QueryMsg { /// Show the Config. #[returns(ConfigResponse)] Config {}, - #[returns(AdminResponse)] + #[returns(cw_controllers::AdminResponse)] Admin {}, /// Query if a given cw20 contract is allowed. #[returns(AllowedResponse)] diff --git a/contracts/cw3-fixed-multisig/src/msg.rs b/contracts/cw3-fixed-multisig/src/msg.rs index ea40680c6..c21908c33 100644 --- a/contracts/cw3-fixed-multisig/src/msg.rs +++ b/contracts/cw3-fixed-multisig/src/msg.rs @@ -1,10 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::{ - ProposalListResponse, ProposalResponse, Vote, VoteListResponse, VoteResponse, - VoterListResponse, VoterResponse, -}; -use cw_utils::{Duration, Expiration, Threshold, ThresholdResponse}; +use cw3::Vote; +use cw_utils::{Duration, Expiration, Threshold}; #[cw_serde] pub struct InstantiateMsg { @@ -45,31 +42,31 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(ThresholdResponse)] + #[returns(cw_utils::ThresholdResponse)] Threshold {}, - #[returns(ProposalResponse)] + #[returns(cw3::ProposalResponse)] Proposal { proposal_id: u64 }, - #[returns(ProposalListResponse)] + #[returns(cw3::ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - #[returns(ProposalListResponse)] + #[returns(cw3::ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - #[returns(VoteResponse)] + #[returns(cw3::VoteResponse)] Vote { proposal_id: u64, voter: String }, - #[returns(VoteListResponse)] + #[returns(cw3::VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - #[returns(VoterResponse)] + #[returns(cw3::VoterResponse)] Voter { address: String }, - #[returns(VoterListResponse)] + #[returns(cw3::VoterListResponse)] ListVoters { start_after: Option, limit: Option, diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index 13a8ac52e..f91e8abff 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -1,11 +1,8 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::{ - ProposalListResponse, ProposalResponse, Vote, VoteListResponse, VoteResponse, - VoterListResponse, VoterResponse, -}; +use cw3::Vote; use cw4::MemberChangedHookMsg; -use cw_utils::{Duration, Expiration, Threshold, ThresholdResponse}; +use cw_utils::{Duration, Expiration, Threshold}; use crate::state::Executor; @@ -48,31 +45,31 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(ThresholdResponse)] + #[returns(cw_utils::ThresholdResponse)] Threshold {}, - #[returns(ProposalResponse)] + #[returns(cw3::ProposalResponse)] Proposal { proposal_id: u64 }, - #[returns(ProposalListResponse)] + #[returns(cw3::ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - #[returns(ProposalListResponse)] + #[returns(cw3::ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - #[returns(VoteResponse)] + #[returns(cw3::VoteResponse)] Vote { proposal_id: u64, voter: String }, - #[returns(VoteListResponse)] + #[returns(cw3::VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - #[returns(VoterResponse)] + #[returns(cw3::VoterResponse)] Voter { address: String }, - #[returns(VoterListResponse)] + #[returns(cw3::VoterListResponse)] ListVoters { start_after: Option, limit: Option, diff --git a/contracts/cw4-group/src/msg.rs b/contracts/cw4-group/src/msg.rs index dd751a948..823359ed2 100644 --- a/contracts/cw4-group/src/msg.rs +++ b/contracts/cw4-group/src/msg.rs @@ -1,6 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cw4::{Member, MemberListResponse, MemberResponse, TotalWeightResponse}; -use cw_controllers::{AdminResponse, HooksResponse}; +use cw4::Member; #[cw_serde] pub struct InstantiateMsg { @@ -29,21 +28,21 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(AdminResponse)] + #[returns(cw_controllers::AdminResponse)] Admin {}, - #[returns(TotalWeightResponse)] + #[returns(cw4::TotalWeightResponse)] TotalWeight {}, - #[returns(MemberListResponse)] + #[returns(cw4::MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - #[returns(MemberResponse)] + #[returns(cw4::MemberResponse)] Member { addr: String, at_height: Option, }, /// Shows all registered hooks. - #[returns(HooksResponse)] + #[returns(cw_controllers::HooksResponse)] Hooks {}, } diff --git a/contracts/cw4-stake/src/msg.rs b/contracts/cw4-stake/src/msg.rs index 04c1423db..e1bcc7a5a 100644 --- a/contracts/cw4-stake/src/msg.rs +++ b/contracts/cw4-stake/src/msg.rs @@ -2,8 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; use cw20::{Cw20ReceiveMsg, Denom}; -use cw4::{MemberListResponse, MemberResponse, TotalWeightResponse}; -pub use cw_controllers::{AdminResponse, ClaimsResponse, HooksResponse}; +pub use cw_controllers::ClaimsResponse; use cw_utils::Duration; #[cw_serde] @@ -51,28 +50,28 @@ pub enum ReceiveMsg { #[derive(QueryResponses)] pub enum QueryMsg { /// Claims shows the tokens in process of unbonding for this address - #[returns(ClaimsResponse)] + #[returns(cw_controllers::ClaimsResponse)] Claims { address: String }, // Show the number of tokens currently staked by this address. #[returns(StakedResponse)] Staked { address: String }, - #[returns(AdminResponse)] + #[returns(cw_controllers::AdminResponse)] Admin {}, - #[returns(TotalWeightResponse)] + #[returns(cw4::TotalWeightResponse)] TotalWeight {}, - #[returns(MemberListResponse)] + #[returns(cw4::MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - #[returns(MemberResponse)] + #[returns(cw4::MemberResponse)] Member { addr: String, at_height: Option, }, /// Shows all registered hooks. - #[returns(HooksResponse)] + #[returns(cw_controllers::HooksResponse)] Hooks {}, } From be71b544f2dcf43a342b2b44cbc3a562b0346c41 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 31 Aug 2022 00:12:29 +0200 Subject: [PATCH 431/631] fix CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b2f1d6858..97a745e89 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -597,7 +597,7 @@ jobs: for C in ./contracts/*/ do echo "Compiling `basename $C`..." - (cd $C && cargo build --release --target wasm32-unknown-unknown --locked) + (cd $C && cargo build --release --lib --target wasm32-unknown-unknown --locked) done - run: name: Install check_contract From 4967190e8d98bea23d3bd6439bd13104120f2a6d Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 31 Aug 2022 00:19:43 +0200 Subject: [PATCH 432/631] CI: update check_contract --- .circleci/config.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 97a745e89..aeda41084 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -578,7 +578,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.58.1 + - image: rust:1.59.0 steps: - checkout: path: ~/project @@ -587,7 +587,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.59.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -600,22 +600,17 @@ jobs: (cd $C && cargo build --release --lib --target wasm32-unknown-unknown --locked) done - run: - name: Install check_contract + name: Install cosmwasm-check # Uses --debug for compilation speed - command: cargo install --debug --version 1.0.0 --features iterator --example check_contract -- cosmwasm-vm + command: cargo install --debug --version 1.1.0-rc.1 cosmwasm-check - save_cache: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.59.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts - command: | - for W in ./target/wasm32-unknown-unknown/release/*.wasm - do - echo -n "Checking `basename $W`... " - check_contract $W - done + command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm package_multi_test: docker: From 1fd29f7fd547314e2d092fef91b7914d0859d04a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 5 Sep 2022 13:17:44 +0200 Subject: [PATCH 433/631] Update to CosmWasm 1.1.0 --- Cargo.lock | 24 ++++++++++++------------ contracts/cw1-subkeys/Cargo.toml | 4 ++-- contracts/cw1-whitelist-ng/Cargo.toml | 4 ++-- contracts/cw1-whitelist/Cargo.toml | 4 ++-- contracts/cw1155-base/Cargo.toml | 4 ++-- contracts/cw20-base/Cargo.toml | 4 ++-- contracts/cw20-ics20/Cargo.toml | 4 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 4 ++-- contracts/cw3-flex-multisig/Cargo.toml | 4 ++-- contracts/cw4-group/Cargo.toml | 4 ++-- contracts/cw4-stake/Cargo.toml | 4 ++-- packages/controllers/Cargo.toml | 4 ++-- packages/cw1/Cargo.toml | 4 ++-- packages/cw1155/Cargo.toml | 4 ++-- packages/cw2/Cargo.toml | 4 ++-- packages/cw20/Cargo.toml | 4 ++-- packages/cw3/Cargo.toml | 4 ++-- packages/cw4/Cargo.toml | 4 ++-- packages/multi-test/Cargo.toml | 4 ++-- packages/storage-macro/Cargo.toml | 2 +- packages/storage-plus/Cargo.toml | 2 +- packages/utils/Cargo.toml | 4 ++-- 22 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb6fd8a45..11f0a0b9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,9 +173,9 @@ checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" [[package]] name = "cosmwasm-crypto" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090841687cec685dd6a1914b8c9504e716b83d2f17a583af6f3b77a8034cfdb1" +checksum = "16c50d753d44148c7ff3279ac44b87b5b91e790f4c70db0e3900df211310a2bf" dependencies = [ "digest 0.10.3", "ed25519-zebra", @@ -186,18 +186,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73196b5f87f50ac75eb716ce9f0fc0aaa80394ba742382f7714c38f9b5420e97" +checksum = "9053ebe2ad85831e9f9e2124fa2b22807528a78b25cc447483ce2a4aadfba394" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e420480fd492336e849bf1c24f7339abf12a8e2afa250bc6865d67cd84cf4b4" +checksum = "8c742fc698a88cf02ea304cc2b5bc18ef975c5bb9eff93c3e44d2cd565e1d458" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf475a7f85987e1f5ef623c510a39d8d294d1ee6807c68f08d96ada6905e850d" +checksum = "88a7c4c07be11add09dd3af3064c4f4cbc2dc99c6859129bdaf820131730e996" dependencies = [ "proc-macro2", "quote", @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e13a4bfb42768d53db5d930ce276356958a8f2d4da89ac44b3841393d1e45b" +checksum = "eb8da0ae28693d892af2944319b48adc23c42725dc0fe7271b8baa38c10865da" dependencies = [ "base64", "cosmwasm-crypto", @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.1.0-rc.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf3cd03affeaea2e250f431024fff6cee96f1e9c0f79b4202cb6554c917ba00" +checksum = "3205d5210ba4c7b7cc7329b9607c37d00dc08263c2479fd99541a2194ebe3b22" dependencies = [ "cosmwasm-std", "serde", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 560c6d88a..12a571ef9 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,12 +19,12 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library"] } -cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } +cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index a452aa3b6..2beb4173b 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -22,11 +22,11 @@ querier = ["library"] multitest = ["cw-multi-test", "anyhow"] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } +cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 2c2c57a03..9b318d6e6 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,11 +19,11 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw1 = { path = "../../packages/cw1", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } +cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 4daed8a0f..f5b5dc207 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw1155 = { path = "../../packages/cw1155", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.20" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 08ba32a88..3969340cb 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index cfcaae353..89a1225e8 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -18,11 +18,11 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1", features = ["stargate"] } +cosmwasm-std = { version = "1.1.0", features = ["stargate"] } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } schemars = "0.8.1" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index db016d6ab..4278ba1c0 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -18,12 +18,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 9eb2303ac..ce537a781 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -18,14 +18,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw3 = { path = "../../packages/cw3", version = "0.14.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.14.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index a23768a9c..a4348540a 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -26,13 +26,13 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index e7ce93bde..75c05cd20 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -26,14 +26,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0-rc.1" } +cosmwasm-schema = { version = "1.1.0" } cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw2 = { path = "../../packages/cw2", version = "0.14.0" } cw4 = { path = "../../packages/cw4", version = "0.14.0" } cw20 = { path = "../../packages/cw20", version = "0.14.0" } cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 03feddadd..5003031a2 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -11,8 +11,8 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" cw-utils = { path = "../utils", version = "0.14.0" } cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } schemars = "0.8.1" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 6d839df43..95d002119 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 55b3b1f27..a8b826bf0 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = { version = "1.1.0-rc.1" } +cosmwasm-schema = "1.1.0" +cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 66b87431d..e72c35508 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -9,8 +9,8 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } +cosmwasm-schema = "1.1.0" +cosmwasm-std = { version = "1.1.0", default-features = false } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index feb0d9ffc..5ebb89295 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 10b89cc6d..cb9f0d8bd 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index cc5d212c8..45259acba 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index c1a07b88c..a46d37163 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -19,8 +19,8 @@ backtrace = ["anyhow/backtrace"] [dependencies] cw-utils = { path = "../../packages/utils", version = "0.14.0" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0"} -cosmwasm-std = { version = "1.1.0-rc.1", features = ["staking"] } -cosmwasm-storage = "1.1.0-rc.1" +cosmwasm-std = { version = "1.1.0", features = ["staking"] } +cosmwasm-storage = "1.1.0" itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index ab18fc4af..d7153fc9b 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -17,5 +17,5 @@ syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] cw-storage-plus = { version = "<=0.14.0, >=0.13.4", path = "../storage-plus" } -cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } +cosmwasm-std = { version = "1.1.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 8ec378573..9592530a1 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -18,7 +18,7 @@ macro = ["cw-storage-macro"] bench = false [dependencies] -cosmwasm-std = { version = "1.1.0-rc.1", default-features = false } +cosmwasm-std = { version = "1.1.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } cw-storage-macro = { version = "0.14.0", optional = true, path = "../storage-macro" } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 26817784d..95b4b7044 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -11,8 +11,8 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-schema = "1.1.0-rc.1" -cosmwasm-std = "1.1.0-rc.1" +cosmwasm-schema = "1.1.0" +cosmwasm-std = "1.1.0" cw2 = { path = "../../packages/cw2", version = "0.14.0" } schemars = "0.8.1" semver = "1" From 8de8ad1fd849eaf1781e516b5009caf2963f52c5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 12:11:42 +0200 Subject: [PATCH 434/631] Add tests for allowance expiration validation --- contracts/cw20-base/src/allowances.rs | 77 ++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 37dcbf459..83e6ef767 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -9,7 +9,7 @@ use crate::state::{ALLOWANCES, ALLOWANCES_SPENDER, BALANCES, TOKEN_INFO}; pub fn execute_increase_allowance( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, spender: String, amount: Uint128, @@ -748,4 +748,79 @@ mod tests { let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Expired {}); } + + #[test] + fn no_past_expiration() { + let mut deps = mock_dependencies_with_balance(&coins(2, "token")); + + let owner = String::from("addr0001"); + let spender = String::from("addr0002"); + let info = mock_info(owner.as_ref(), &[]); + let env = mock_env(); + do_instantiate(deps.as_mut(), owner.clone(), Uint128::new(12340000)); + + // set allowance with height expiration at current block height + let expires = Expiration::AtHeight(env.block.height); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender.clone(), + amount: Uint128::new(7777), + expires: Some(expires), + }; + + // ensure it is rejected + assert_eq!(Err(ContractError::Expired {}), execute(deps.as_mut(), env.clone(), info.clone(), msg)); + + // set allowance with time expiration in the past + let expires = Expiration::AtTime(env.block.time.minus_seconds(1)); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender.clone(), + amount: Uint128::new(7777), + expires: Some(expires), + }; + + // ensure it is rejected + assert_eq!(Err(ContractError::Expired {}), execute(deps.as_mut(), env.clone(), info.clone(), msg)); + + // set allowance with height expiration at next block height + let expires = Expiration::AtHeight(env.block.height + 1); + let allow = Uint128::new(7777); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender.clone(), + amount: allow, + expires: Some(expires), + }; + + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + // ensure it looks good + let allowance = query_allowance(deps.as_ref(), owner.clone(), spender.clone()).unwrap(); + assert_eq!( + allowance, + AllowanceResponse { + allowance: allow, + expires + } + ); + + // set allowance with time expiration in the future + let expires = Expiration::AtTime(env.block.time.plus_seconds(10)); + let allow = Uint128::new(7777); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender.clone(), + amount: allow, + expires: Some(expires), + }; + + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + // ensure it looks good + let allowance = query_allowance(deps.as_ref(), owner.clone(), spender.clone()).unwrap(); + assert_eq!( + allowance, + AllowanceResponse { + allowance: allow + allow, + expires + } + ); + } } From c8dc4937bcb2809535d8b0fac78dc0cfe4ff87aa Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 5 Sep 2022 13:19:17 +0200 Subject: [PATCH 435/631] Update CI with cosmwasm-check 1.1.0 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index aeda41084..c18302790 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -602,7 +602,7 @@ jobs: - run: name: Install cosmwasm-check # Uses --debug for compilation speed - command: cargo install --debug --version 1.1.0-rc.1 cosmwasm-check + command: cargo install --debug --version 1.1.0 cosmwasm-check - save_cache: paths: - /usr/local/cargo/registry From 485277610b0d952c25ef107adea1fd5eef869309 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 13:22:14 +0200 Subject: [PATCH 436/631] Validate that expiration is not expired when set --- contracts/cw20-base/src/allowances.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 83e6ef767..874bcfb57 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -20,9 +20,12 @@ pub fn execute_increase_allowance( return Err(ContractError::CannotSetOwnAccount {}); } - let update_fn = |allow: Option| -> StdResult<_> { + let update_fn = |allow: Option| -> Result<_, _> { let mut val = allow.unwrap_or_default(); if let Some(exp) = expires { + if exp.is_expired(&env.block) { + return Err(ContractError::Expired { }); + } val.expires = exp; } val.allowance += amount; From acd61c3fb5f2aa79fd21aa0d9a9db7af4c72b814 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 13:22:21 +0200 Subject: [PATCH 437/631] Fix tests --- contracts/cw20-base/src/allowances.rs | 39 +++++++++++++++------------ contracts/cw20-base/src/contract.rs | 2 +- contracts/cw20-base/src/enumerable.rs | 4 +-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 874bcfb57..401057cad 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -303,7 +303,7 @@ mod tests { // set allowance with height expiration let allow1 = Uint128::new(7777); - let expires = Expiration::AtHeight(5432); + let expires = Expiration::AtHeight(123_456); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: allow1, @@ -396,7 +396,7 @@ mod tests { // set allowance with height expiration let allow1 = Uint128::new(7777); - let expires = Expiration::AtHeight(5432); + let expires = Expiration::AtHeight(123_456); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: allow1, @@ -551,15 +551,17 @@ mod tests { let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert!(matches!(err, ContractError::Std(StdError::Overflow { .. }))); - // let us increase limit, but set the expiration (default env height is 12_345) + // let us increase limit, but set the expiration to expire in the next block let info = mock_info(owner.as_ref(), &[]); - let env = mock_env(); + let mut env = mock_env(); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: Uint128::new(1000), - expires: Some(Expiration::AtHeight(env.block.height)), + expires: Some(Expiration::AtHeight(env.block.height + 1)), }; - execute(deps.as_mut(), env, info, msg).unwrap(); + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + env.block.height += 1; // we should now get the expiration error let msg = ExecuteMsg::TransferFrom { @@ -568,7 +570,6 @@ mod tests { amount: Uint128::new(33443), }; let info = mock_info(spender.as_ref(), &[]); - let env = mock_env(); let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Expired {}); } @@ -628,15 +629,18 @@ mod tests { let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert!(matches!(err, ContractError::Std(StdError::Overflow { .. }))); - // let us increase limit, but set the expiration (default env height is 12_345) + // let us increase limit, but set the expiration to expire in the next block let info = mock_info(owner.as_ref(), &[]); - let env = mock_env(); + let mut env = mock_env(); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: Uint128::new(1000), - expires: Some(Expiration::AtHeight(env.block.height)), + expires: Some(Expiration::AtHeight(env.block.height + 1)), }; - execute(deps.as_mut(), env, info, msg).unwrap(); + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // increase block height, so the limit is expired now + env.block.height += 1; // we should now get the expiration error let msg = ExecuteMsg::BurnFrom { @@ -644,7 +648,6 @@ mod tests { amount: Uint128::new(33443), }; let info = mock_info(spender.as_ref(), &[]); - let env = mock_env(); let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Expired {}); } @@ -729,15 +732,18 @@ mod tests { let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert!(matches!(err, ContractError::Std(StdError::Overflow { .. }))); - // let us increase limit, but set the expiration to current block (expired) + // let us increase limit, but set the expiration to the next block let info = mock_info(owner.as_ref(), &[]); - let env = mock_env(); + let mut env = mock_env(); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: Uint128::new(1000), - expires: Some(Expiration::AtHeight(env.block.height)), + expires: Some(Expiration::AtHeight(env.block.height + 1)), }; - execute(deps.as_mut(), env, info, msg).unwrap(); + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // increase block height, so the limit is expired now + env.block.height += 1; // we should now get the expiration error let msg = ExecuteMsg::SendFrom { @@ -747,7 +753,6 @@ mod tests { msg: send_msg, }; let info = mock_info(spender.as_ref(), &[]); - let env = mock_env(); let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Expired {}); } diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 029af5629..049dcbfaa 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -1403,7 +1403,7 @@ mod tests { // Set allowance let allow1 = Uint128::new(7777); - let expires = Expiration::AtHeight(5432); + let expires = Expiration::AtHeight(123_456); let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cw20_addr.to_string(), msg: to_binary(&ExecuteMsg::IncreaseAllowance { diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 8022fe9bd..f465134d2 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -127,7 +127,7 @@ mod tests { // set allowance with height expiration let allow1 = Uint128::new(7777); - let expires = Expiration::AtHeight(5432); + let expires = Expiration::AtHeight(123_456); let msg = ExecuteMsg::IncreaseAllowance { spender: spender1.clone(), amount: allow1, @@ -192,7 +192,7 @@ mod tests { // set allowance with height expiration let allow1 = Uint128::new(7777); - let expires = Expiration::AtHeight(5432); + let expires = Expiration::AtHeight(123_456); let msg = ExecuteMsg::IncreaseAllowance { spender: spender.clone(), amount: allow1, From 299a47d841696c2acd3e87fbbfe2735701deb5f9 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 14:05:32 +0200 Subject: [PATCH 438/631] Validate allowance expiration when decreasing --- contracts/cw20-base/src/allowances.rs | 57 ++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 401057cad..0f410d7cc 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -24,7 +24,7 @@ pub fn execute_increase_allowance( let mut val = allow.unwrap_or_default(); if let Some(exp) = expires { if exp.is_expired(&env.block) { - return Err(ContractError::Expired { }); + return Err(ContractError::Expired {}); } val.expires = exp; } @@ -45,7 +45,7 @@ pub fn execute_increase_allowance( pub fn execute_decrease_allowance( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, spender: String, amount: Uint128, @@ -71,6 +71,9 @@ pub fn execute_decrease_allowance( .checked_sub(amount) .map_err(StdError::overflow)?; if let Some(exp) = expires { + if exp.is_expired(&env.block) { + return Err(ContractError::Expired {}); + } allowance.expires = exp; } ALLOWANCES.save(deps.storage, key, &allowance)?; @@ -774,9 +777,12 @@ mod tests { amount: Uint128::new(7777), expires: Some(expires), }; - + // ensure it is rejected - assert_eq!(Err(ContractError::Expired {}), execute(deps.as_mut(), env.clone(), info.clone(), msg)); + assert_eq!( + Err(ContractError::Expired {}), + execute(deps.as_mut(), env.clone(), info.clone(), msg) + ); // set allowance with time expiration in the past let expires = Expiration::AtTime(env.block.time.minus_seconds(1)); @@ -787,7 +793,10 @@ mod tests { }; // ensure it is rejected - assert_eq!(Err(ContractError::Expired {}), execute(deps.as_mut(), env.clone(), info.clone(), msg)); + assert_eq!( + Err(ContractError::Expired {}), + execute(deps.as_mut(), env.clone(), info.clone(), msg) + ); // set allowance with height expiration at next block height let expires = Expiration::AtHeight(env.block.height + 1); @@ -826,7 +835,43 @@ mod tests { assert_eq!( allowance, AllowanceResponse { - allowance: allow + allow, + allowance: allow + allow, // we increased twice + expires + } + ); + + // decrease with height expiration at current block height + let expires = Expiration::AtHeight(env.block.height); + let allow = Uint128::new(7777); + let msg = ExecuteMsg::IncreaseAllowance { + spender: spender.clone(), + amount: allow, + expires: Some(expires), + }; + + // ensure it is rejected + assert_eq!( + Err(ContractError::Expired {}), + execute(deps.as_mut(), env.clone(), info.clone(), msg) + ); + + // decrease with height expiration at next block height + let expires = Expiration::AtHeight(env.block.height + 1); + let allow = Uint128::new(7777); + let msg = ExecuteMsg::DecreaseAllowance { + spender: spender.clone(), + amount: allow, + expires: Some(expires), + }; + + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + // ensure it looks good + let allowance = query_allowance(deps.as_ref(), owner.clone(), spender.clone()).unwrap(); + assert_eq!( + allowance, + AllowanceResponse { + allowance: allow, expires } ); From 7afa2c407ba9d5714d4623cb5a617f8ed462aac2 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 16:40:06 +0200 Subject: [PATCH 439/631] Add own error variant for expiration validation --- contracts/cw20-base/src/allowances.rs | 10 +++++----- contracts/cw20-base/src/error.rs | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 0f410d7cc..ef5f5fd18 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -24,7 +24,7 @@ pub fn execute_increase_allowance( let mut val = allow.unwrap_or_default(); if let Some(exp) = expires { if exp.is_expired(&env.block) { - return Err(ContractError::Expired {}); + return Err(ContractError::InvalidExpiration {}); } val.expires = exp; } @@ -72,7 +72,7 @@ pub fn execute_decrease_allowance( .map_err(StdError::overflow)?; if let Some(exp) = expires { if exp.is_expired(&env.block) { - return Err(ContractError::Expired {}); + return Err(ContractError::InvalidExpiration {}); } allowance.expires = exp; } @@ -780,7 +780,7 @@ mod tests { // ensure it is rejected assert_eq!( - Err(ContractError::Expired {}), + Err(ContractError::InvalidExpiration {}), execute(deps.as_mut(), env.clone(), info.clone(), msg) ); @@ -794,7 +794,7 @@ mod tests { // ensure it is rejected assert_eq!( - Err(ContractError::Expired {}), + Err(ContractError::InvalidExpiration {}), execute(deps.as_mut(), env.clone(), info.clone(), msg) ); @@ -851,7 +851,7 @@ mod tests { // ensure it is rejected assert_eq!( - Err(ContractError::Expired {}), + Err(ContractError::InvalidExpiration {}), execute(deps.as_mut(), env.clone(), info.clone(), msg) ); diff --git a/contracts/cw20-base/src/error.rs b/contracts/cw20-base/src/error.rs index a1a63967d..7cc2af491 100644 --- a/contracts/cw20-base/src/error.rs +++ b/contracts/cw20-base/src/error.rs @@ -33,6 +33,9 @@ pub enum ContractError { #[error("Invalid png header")] InvalidPngHeader {}, + #[error("Invalid expiration value")] + InvalidExpiration {}, + #[error("Duplicate initial balance addresses")] DuplicateInitialBalanceAddresses {}, } From 5d7e213d6a9f872c16ea04548ebc39412fc8317d Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 5 Sep 2022 17:00:47 +0200 Subject: [PATCH 440/631] Fix clippy warnings --- contracts/cw20-base/src/allowances.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index ef5f5fd18..38b36da46 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -864,10 +864,10 @@ mod tests { expires: Some(expires), }; - execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + execute(deps.as_mut(), env, info, msg).unwrap(); // ensure it looks good - let allowance = query_allowance(deps.as_ref(), owner.clone(), spender.clone()).unwrap(); + let allowance = query_allowance(deps.as_ref(), owner, spender).unwrap(); assert_eq!( allowance, AllowanceResponse { From 70e8726c1fcdc19bfb07456b2a7f5df9bb00ce7f Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 5 Sep 2022 19:46:13 +0200 Subject: [PATCH 441/631] fix `cargo wasm` --- contracts/cw1-subkeys/.cargo/config | 4 ++-- contracts/cw1-whitelist-ng/.cargo/config | 4 ++-- contracts/cw1-whitelist/.cargo/config | 4 ++-- contracts/cw1155-base/.cargo/config | 4 ++-- contracts/cw20-base/.cargo/config | 4 ++-- contracts/cw20-ics20/.cargo/config | 4 ++-- contracts/cw3-fixed-multisig/.cargo/config | 4 ++-- contracts/cw3-flex-multisig/.cargo/config | 4 ++-- contracts/cw4-group/.cargo/config | 4 ++-- contracts/cw4-stake/.cargo/config | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contracts/cw1-subkeys/.cargo/config b/contracts/cw1-subkeys/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw1-subkeys/.cargo/config +++ b/contracts/cw1-subkeys/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw1-whitelist-ng/.cargo/config b/contracts/cw1-whitelist-ng/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw1-whitelist-ng/.cargo/config +++ b/contracts/cw1-whitelist-ng/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw1-whitelist/.cargo/config b/contracts/cw1-whitelist/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw1-whitelist/.cargo/config +++ b/contracts/cw1-whitelist/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw1155-base/.cargo/config b/contracts/cw1155-base/.cargo/config index 08d13a665..de2d36ac7 100644 --- a/contracts/cw1155-base/.cargo/config +++ b/contracts/cw1155-base/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" schema = "run --bin schema" diff --git a/contracts/cw20-base/.cargo/config b/contracts/cw20-base/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw20-base/.cargo/config +++ b/contracts/cw20-base/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw20-ics20/.cargo/config b/contracts/cw20-ics20/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw20-ics20/.cargo/config +++ b/contracts/cw20-ics20/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw3-fixed-multisig/.cargo/config b/contracts/cw3-fixed-multisig/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw3-fixed-multisig/.cargo/config +++ b/contracts/cw3-fixed-multisig/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw3-flex-multisig/.cargo/config b/contracts/cw3-flex-multisig/.cargo/config index 4e0626844..f5174787c 100644 --- a/contracts/cw3-flex-multisig/.cargo/config +++ b/contracts/cw3-flex-multisig/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" schema = "run --bin schema" diff --git a/contracts/cw4-group/.cargo/config b/contracts/cw4-group/.cargo/config index 08d13a665..de2d36ac7 100644 --- a/contracts/cw4-group/.cargo/config +++ b/contracts/cw4-group/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" schema = "run --bin schema" diff --git a/contracts/cw4-stake/.cargo/config b/contracts/cw4-stake/.cargo/config index 08d13a665..de2d36ac7 100644 --- a/contracts/cw4-stake/.cargo/config +++ b/contracts/cw4-stake/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" schema = "run --bin schema" From d3f4bd5b8c9f96fc8c87b7dd16331880a2833cc5 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 09:33:04 +0200 Subject: [PATCH 442/631] cw4 contracts: clean up imports --- contracts/cw4-group/src/bin/schema.rs | 3 +-- contracts/cw4-stake/src/bin/schema.rs | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/contracts/cw4-group/src/bin/schema.rs b/contracts/cw4-group/src/bin/schema.rs index 20fdf9b16..aca81b1bf 100644 --- a/contracts/cw4-group/src/bin/schema.rs +++ b/contracts/cw4-group/src/bin/schema.rs @@ -1,7 +1,6 @@ use cosmwasm_schema::write_api; -pub use cw4::{AdminResponse, MemberListResponse, MemberResponse, TotalWeightResponse}; -pub use cw4_group::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cw4_group::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/cw4-stake/src/bin/schema.rs b/contracts/cw4-stake/src/bin/schema.rs index b6d3f29ba..cc9b421db 100644 --- a/contracts/cw4-stake/src/bin/schema.rs +++ b/contracts/cw4-stake/src/bin/schema.rs @@ -1,9 +1,6 @@ use cosmwasm_schema::write_api; -pub use cw4::{AdminResponse, MemberListResponse, MemberResponse, TotalWeightResponse}; -pub use cw4_stake::msg::{ - ClaimsResponse, ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg, StakedResponse, -}; +use cw4_stake::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { From 16bbdc69ab703eeb20637c4eb01fe24b24807644 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:25:36 +0200 Subject: [PATCH 443/631] packages: move schema gen out of `examples` --- packages/cw1/.cargo/config | 6 +++--- packages/cw1/{examples => src/bin}/schema.rs | 0 packages/cw1155/.cargo/config | 6 +++--- packages/cw1155/{examples => src/bin}/schema.rs | 0 packages/cw20/.cargo/config | 6 +++--- packages/cw20/{examples => src/bin}/schema.rs | 0 packages/cw3/.cargo/config | 6 +++--- packages/cw3/{examples => src/bin}/schema.rs | 0 packages/cw4/.cargo/config | 6 +++--- packages/cw4/{examples => src/bin}/schema.rs | 0 10 files changed, 15 insertions(+), 15 deletions(-) rename packages/cw1/{examples => src/bin}/schema.rs (100%) rename packages/cw1155/{examples => src/bin}/schema.rs (100%) rename packages/cw20/{examples => src/bin}/schema.rs (100%) rename packages/cw3/{examples => src/bin}/schema.rs (100%) rename packages/cw4/{examples => src/bin}/schema.rs (100%) diff --git a/packages/cw1/.cargo/config b/packages/cw1/.cargo/config index b613a59f1..628e18e5b 100644 --- a/packages/cw1/.cargo/config +++ b/packages/cw1/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" diff --git a/packages/cw1/examples/schema.rs b/packages/cw1/src/bin/schema.rs similarity index 100% rename from packages/cw1/examples/schema.rs rename to packages/cw1/src/bin/schema.rs diff --git a/packages/cw1155/.cargo/config b/packages/cw1155/.cargo/config index b613a59f1..628e18e5b 100644 --- a/packages/cw1155/.cargo/config +++ b/packages/cw1155/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" diff --git a/packages/cw1155/examples/schema.rs b/packages/cw1155/src/bin/schema.rs similarity index 100% rename from packages/cw1155/examples/schema.rs rename to packages/cw1155/src/bin/schema.rs diff --git a/packages/cw20/.cargo/config b/packages/cw20/.cargo/config index b613a59f1..628e18e5b 100644 --- a/packages/cw20/.cargo/config +++ b/packages/cw20/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" diff --git a/packages/cw20/examples/schema.rs b/packages/cw20/src/bin/schema.rs similarity index 100% rename from packages/cw20/examples/schema.rs rename to packages/cw20/src/bin/schema.rs diff --git a/packages/cw3/.cargo/config b/packages/cw3/.cargo/config index b613a59f1..628e18e5b 100644 --- a/packages/cw3/.cargo/config +++ b/packages/cw3/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" diff --git a/packages/cw3/examples/schema.rs b/packages/cw3/src/bin/schema.rs similarity index 100% rename from packages/cw3/examples/schema.rs rename to packages/cw3/src/bin/schema.rs diff --git a/packages/cw4/.cargo/config b/packages/cw4/.cargo/config index b613a59f1..628e18e5b 100644 --- a/packages/cw4/.cargo/config +++ b/packages/cw4/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" diff --git a/packages/cw4/examples/schema.rs b/packages/cw4/src/bin/schema.rs similarity index 100% rename from packages/cw4/examples/schema.rs rename to packages/cw4/src/bin/schema.rs From b5de911bcba34b5eb57533116e1484a516d2b92a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:33:30 +0200 Subject: [PATCH 444/631] CI: upload unified .json instead of tarball for contract schemas --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c18302790..6f70565d4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -784,7 +784,7 @@ jobs: for C in ./contracts/*/ do echo "Generating schema for $C ..." - (cd $C && cargo schema --locked && tar -zcf ~/project/schemas/$(basename $(pwd))_schema.tar.gz ./schema) + (cd $C && cargo schema --locked && mv ./schema/$(basename $(pwd)).json ~/project/schemas/) done - run: name: Show data From 7c9db36d40424a6cd448c2f58c486a3a688731f7 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:45:33 +0200 Subject: [PATCH 445/631] Update .circleci/config.yml Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f70565d4..c02283765 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -784,7 +784,7 @@ jobs: for C in ./contracts/*/ do echo "Generating schema for $C ..." - (cd $C && cargo schema --locked && mv ./schema/$(basename $(pwd)).json ~/project/schemas/) + (cd $C && cargo schema --locked && mv ./schema/*.json ~/project/schemas/) done - run: name: Show data From f8549cedfc3fbe47f69de2c4a6dcba4fd0f1a856 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:50:49 +0200 Subject: [PATCH 446/631] test schema publishing --- .circleci/config.yml | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c02283765..880c16009 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,12 +47,7 @@ workflows: only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ branches: ignore: /.*/ - - build_and_upload_schemas: - filters: - tags: - only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ - branches: - ignore: /.*/ + - build_and_upload_schemas jobs: contract_cw1_subkeys: @@ -789,15 +784,15 @@ jobs: - run: name: Show data command: ls -l ./schemas - - run: - name: Publish schemas on GitHub - command: | - TAG="$CIRCLE_TAG" - TITLE="$TAG" - BODY="Attached there are some schemas and build artifacts generated at this tag. Those are for development purposes only! Please use crates.io to find the packages of this release." - ghr -t "$GITHUB_TOKEN" \ - -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ - -c "$CIRCLE_SHA1" \ - -n "$TITLE" -b "$BODY" \ - -replace \ - "$TAG" ./schemas/ + # - run: + # name: Publish schemas on GitHub + # command: | + # TAG="$CIRCLE_TAG" + # TITLE="$TAG" + # BODY="Attached there are some schemas and build artifacts generated at this tag. Those are for development purposes only! Please use crates.io to find the packages of this release." + # ghr -t "$GITHUB_TOKEN" \ + # -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ + # -c "$CIRCLE_SHA1" \ + # -n "$TITLE" -b "$BODY" \ + # -replace \ + # "$TAG" ./schemas/ From b4cfc7272a94fae09c0606cb5a197e807a4fbca2 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:53:31 +0200 Subject: [PATCH 447/631] Fix CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 880c16009..908ce49ef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -767,7 +767,7 @@ jobs: - run: name: Build and run schema generator for packages command: | - for S in ./packages/*/examples/schema.rs + for S in ./packages/*/src/bin/schema.rs do P=$(dirname $S)/.. echo "Generating schema for $P ..." From 38a316c927ae01561c5e496bace4152613dfaddb Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 13:56:54 +0200 Subject: [PATCH 448/631] Fix CI again! --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 908ce49ef..178939ca5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -769,7 +769,7 @@ jobs: command: | for S in ./packages/*/src/bin/schema.rs do - P=$(dirname $S)/.. + P=$(dirname $S)/../.. echo "Generating schema for $P ..." (cd $P && cargo schema --locked && tar -zcf ~/project/schemas/$(basename $(pwd))_schema.tar.gz ./schema) done From ac29abc76939e283130991dafedbdcc81a459e7a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 14:07:50 +0200 Subject: [PATCH 449/631] CI: exclude whitelist-ng from schema gen --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 178939ca5..838425a87 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -776,6 +776,7 @@ jobs: - run: name: Build and run schema generator for contracts command: | + export GLOBIGNORE='./contracts/cw1-whitelist-ng/' for C in ./contracts/*/ do echo "Generating schema for $C ..." From f3617ee5e95a6a5e3aa0b9b64a2f6003e65c6752 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 13 Sep 2022 14:12:18 +0200 Subject: [PATCH 450/631] Revert "test schema publishing" This reverts commit f8549cedfc3fbe47f69de2c4a6dcba4fd0f1a856. --- .circleci/config.yml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 838425a87..ccca8273f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,7 +47,12 @@ workflows: only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ branches: ignore: /.*/ - - build_and_upload_schemas + - build_and_upload_schemas: + filters: + tags: + only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ + branches: + ignore: /.*/ jobs: contract_cw1_subkeys: @@ -785,15 +790,15 @@ jobs: - run: name: Show data command: ls -l ./schemas - # - run: - # name: Publish schemas on GitHub - # command: | - # TAG="$CIRCLE_TAG" - # TITLE="$TAG" - # BODY="Attached there are some schemas and build artifacts generated at this tag. Those are for development purposes only! Please use crates.io to find the packages of this release." - # ghr -t "$GITHUB_TOKEN" \ - # -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ - # -c "$CIRCLE_SHA1" \ - # -n "$TITLE" -b "$BODY" \ - # -replace \ - # "$TAG" ./schemas/ + - run: + name: Publish schemas on GitHub + command: | + TAG="$CIRCLE_TAG" + TITLE="$TAG" + BODY="Attached there are some schemas and build artifacts generated at this tag. Those are for development purposes only! Please use crates.io to find the packages of this release." + ghr -t "$GITHUB_TOKEN" \ + -u "$CIRCLE_PROJECT_USERNAME" -r "$CIRCLE_PROJECT_REPONAME" \ + -c "$CIRCLE_SHA1" \ + -n "$TITLE" -b "$BODY" \ + -replace \ + "$TAG" ./schemas/ From 372f7af0987a57c7da5d7ac1d464d43241d6083d Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 14 Sep 2022 05:41:48 +0200 Subject: [PATCH 451/631] Set version: 0.15.0 --- contracts/cw1-subkeys/Cargo.toml | 14 +++++++------- contracts/cw1-whitelist-ng/Cargo.toml | 14 +++++++------- contracts/cw1-whitelist/Cargo.toml | 12 ++++++------ contracts/cw1155-base/Cargo.toml | 10 +++++----- contracts/cw20-base/Cargo.toml | 12 ++++++------ contracts/cw20-ics20/Cargo.toml | 12 ++++++------ contracts/cw3-fixed-multisig/Cargo.toml | 16 ++++++++-------- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++++++--------- contracts/cw4-group/Cargo.toml | 12 ++++++------ contracts/cw4-stake/Cargo.toml | 14 +++++++------- packages/controllers/Cargo.toml | 6 +++--- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 ++-- packages/cw2/Cargo.toml | 4 ++-- packages/cw20/Cargo.toml | 4 ++-- packages/cw3/Cargo.toml | 4 ++-- packages/cw4/Cargo.toml | 4 ++-- packages/multi-test/Cargo.toml | 6 +++--- packages/storage-macro/Cargo.toml | 4 ++-- packages/storage-plus/Cargo.toml | 4 ++-- packages/utils/Cargo.toml | 6 +++--- 21 files changed, 91 insertions(+), 91 deletions(-) diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 12a571ef9..1048e93c6 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -20,16 +20,16 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw1 = { path = "../../packages/cw1", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw1 = { path = "../../packages/cw1", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "0.14.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 2beb4173b..0835031d8 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.14.0" +version = "0.15.0" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -23,19 +23,19 @@ multitest = ["cw-multi-test", "anyhow"] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw1 = { path = "../../packages/cw1", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw1 = { path = "../../packages/cw1", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 9b318d6e6..cbccd3d4d 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw1 = { path = "../../packages/cw1", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw1 = { path = "../../packages/cw1", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index f5b5dc207..1745a0bd7 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.14.0" +version = "0.15.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 3969340cb..e324af8a8 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw20 = { path = "../../packages/cw20", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw20 = { path = "../../packages/cw20", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 89a1225e8..735223fe7 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -19,12 +19,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw20 = { path = "../../packages/cw20", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw20 = { path = "../../packages/cw20", version = "0.15.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 4278ba1c0..32543b216 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -19,16 +19,16 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw3 = { path = "../../packages/cw3", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw3 = { path = "../../packages/cw3", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "0.14.0" } -cw20-base = { path = "../cw20-base", version = "0.14.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } +cw20 = { path = "../../packages/cw20", version = "0.15.0" } +cw20-base = { path = "../cw20-base", version = "0.15.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index ce537a781..bb0d02102 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -19,17 +19,17 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw3 = { path = "../../packages/cw3", version = "0.14.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.14.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw3 = { path = "../../packages/cw3", version = "0.15.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "0.14.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.14.0" } +cw4-group = { path = "../cw4-group", version = "0.15.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index a4348540a..bfff7d61e 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw4 = { path = "../../packages/cw4", version = "0.14.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw4 = { path = "../../packages/cw4", version = "0.15.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 75c05cd20..3e3c7b3b4 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw2 = { path = "../../packages/cw2", version = "0.14.0" } -cw4 = { path = "../../packages/cw4", version = "0.14.0" } -cw20 = { path = "../../packages/cw20", version = "0.14.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw4 = { path = "../../packages/cw4", version = "0.15.0" } +cw20 = { path = "../../packages/cw20", version = "0.15.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 5003031a2..b56979272 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw-utils = { path = "../utils", version = "0.14.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } +cw-utils = { path = "../utils", version = "0.15.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 95d002119..7f52a2492 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index a8b826bf0..6a4888c4a 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.14.0" +version = "0.15.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index e72c35508..f20c1c2d5 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 5ebb89295..5bd8b7727 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index cb9f0d8bd..bb60c2b7f 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.14.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 45259acba..5a48db8bb 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index a46d37163..5092d993b 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -17,8 +17,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.14.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0"} +cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0"} cosmwasm-std = { version = "1.1.0", features = ["staking"] } cosmwasm-storage = "1.1.0" itertools = "0.10.1" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index d7153fc9b..a47530b77 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-macro" -version = "0.14.0" +version = "0.15.0" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" description = "Macro helpers for storage-plus" @@ -16,6 +16,6 @@ proc-macro = true syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] -cw-storage-plus = { version = "<=0.14.0, >=0.13.4", path = "../storage-plus" } +cw-storage-plus = { version = "<=0.15.0, >=0.14.0", path = "../storage-plus" } cosmwasm-std = { version = "1.1.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 9592530a1..5ee6a66fa 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -21,7 +21,7 @@ bench = false cosmwasm-std = { version = "1.1.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.14.0", optional = true, path = "../storage-macro" } +cw-storage-macro = { version = "0.15.0", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = [ "html_reports" ] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 95b4b7044..bf746cfeb 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.14.0" +version = "0.15.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -13,12 +13,12 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw2 = { path = "../../packages/cw2", version = "0.14.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.21" [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.14.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } prost = "0.9" From 66daab8324b4f2bbaed459307c14f3510c70f930 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 14 Sep 2022 05:42:06 +0200 Subject: [PATCH 452/631] Update lock file --- Cargo.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11f0a0b9a..ab2efb6a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,7 +400,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -413,7 +413,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.14.0" +version = "0.15.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "cw-storage-macro" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-std", "criterion", @@ -452,7 +452,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -467,7 +467,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -477,7 +477,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -494,7 +494,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.14.0" +version = "0.15.0" dependencies = [ "anyhow", "assert_matches", @@ -513,7 +513,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.14.0" +version = "0.15.0" dependencies = [ "anyhow", "assert_matches", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -558,7 +558,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -569,7 +569,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -597,7 +597,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -614,7 +614,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -625,7 +625,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -643,7 +643,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -662,7 +662,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.14.0" +version = "0.15.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", From e1edf04c489c53ab1c394d6aa0dea0a3ea68935b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 14 Sep 2022 05:44:45 +0200 Subject: [PATCH 453/631] Update CHANGELOG --- CHANGELOG.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a93aeff8..8322f8747 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,58 @@ ## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.14.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.0...HEAD) + +## [v0.15.0](https://github.com/CosmWasm/cw-plus/tree/v0.15.0) (2022-09-14) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.14.0...v0.15.0) + +**Breaking changes:** + +- Change `MultiIndex` index function signature to include the pk [\#670](https://github.com/CosmWasm/cw-plus/issues/670) +- Improve `MultiIndex` pk deserialization [\#531](https://github.com/CosmWasm/cw-plus/issues/531) + +**Implemented enhancements:** + +- `Prefix::keys` method never fails [\#766](https://github.com/CosmWasm/cw-plus/issues/766) + +**Closed issues:** + +- Adapt build\_and\_upload\_schemas CI job to new schema format [\#795](https://github.com/CosmWasm/cw-plus/issues/795) +- Remove `IntKeyOld` [\#775](https://github.com/CosmWasm/cw-plus/issues/775) +- Can I cover all tests with cw\_multi\_test? [\#771](https://github.com/CosmWasm/cw-plus/issues/771) +- Make cw1155 can add token's url at the first mint [\#764](https://github.com/CosmWasm/cw-plus/issues/764) +- Expose `Response` from contract in cw-multi-test execute [\#763](https://github.com/CosmWasm/cw-plus/issues/763) +- Restructure `Index` trait to allow for more extensive `Index` struct implementation. [\#757](https://github.com/CosmWasm/cw-plus/issues/757) +- Consider moving schema boilerplate from `examples` to a binary crate [\#755](https://github.com/CosmWasm/cw-plus/issues/755) +- Wrong/unclear explanation in IndexedMap docs [\#718](https://github.com/CosmWasm/cw-plus/issues/718) +- Redundant logic in `ThresholdResponse` multisigs [\#677](https://github.com/CosmWasm/cw-plus/issues/677) +- \[cw3-flex/fixed-multisig\] Reject proposals early [\#665](https://github.com/CosmWasm/cw-plus/issues/665) +- cw20 allowance expiration can be set to a block height or timestamp in the past [\#628](https://github.com/CosmWasm/cw-plus/issues/628) +- Add security policy [\#580](https://github.com/CosmWasm/cw-plus/issues/580) +- Update MIGRATING.md doc for multi test [\#490](https://github.com/CosmWasm/cw-plus/issues/490) + +**Merged pull requests:** + +- CI: unified .json schema artifacts for contracts [\#798](https://github.com/CosmWasm/cw-plus/pull/798) ([uint](https://github.com/uint)) +- cw4 contracts: clean up imports and reexports [\#797](https://github.com/CosmWasm/cw-plus/pull/797) ([uint](https://github.com/uint)) +- Fix `cargo wasm` [\#794](https://github.com/CosmWasm/cw-plus/pull/794) ([uint](https://github.com/uint)) +- Validate allowance expiration [\#793](https://github.com/CosmWasm/cw-plus/pull/793) ([chipshort](https://github.com/chipshort)) +- Update to CosmWasm 1.1.0 [\#791](https://github.com/CosmWasm/cw-plus/pull/791) ([uint](https://github.com/uint)) +- CosmWasm `1.1.0-rc.1` [\#789](https://github.com/CosmWasm/cw-plus/pull/789) ([uint](https://github.com/uint)) +- Updating broken link to cw3-flex-multisig [\#787](https://github.com/CosmWasm/cw-plus/pull/787) ([0xriku](https://github.com/0xriku)) +- Multisig status logic follow-up [\#784](https://github.com/CosmWasm/cw-plus/pull/784) ([maurolacy](https://github.com/maurolacy)) +- Multisig status logic [\#783](https://github.com/CosmWasm/cw-plus/pull/783) ([maurolacy](https://github.com/maurolacy)) +- Add primary key to `MultiIndex` index fn params [\#781](https://github.com/CosmWasm/cw-plus/pull/781) ([maurolacy](https://github.com/maurolacy)) +- Fix typo [\#779](https://github.com/CosmWasm/cw-plus/pull/779) ([LeTurt333](https://github.com/LeTurt333)) +- Remove deprecated `IntKeyOld` [\#778](https://github.com/CosmWasm/cw-plus/pull/778) ([ueco-jb](https://github.com/ueco-jb)) +- Small fixes / updates to storage-plus docs [\#777](https://github.com/CosmWasm/cw-plus/pull/777) ([maurolacy](https://github.com/maurolacy)) +- Fix: `Prefix::keys` return errors [\#774](https://github.com/CosmWasm/cw-plus/pull/774) ([maurolacy](https://github.com/maurolacy)) +- Expose cw-multi-test `FailingModule` [\#773](https://github.com/CosmWasm/cw-plus/pull/773) ([dadamu](https://github.com/dadamu)) +- Style: move `InstantiateMsg` validation in impl [\#772](https://github.com/CosmWasm/cw-plus/pull/772) ([etienne-napoleone](https://github.com/etienne-napoleone)) +- Make ExecuteEnv fields public [\#770](https://github.com/CosmWasm/cw-plus/pull/770) ([ismellike](https://github.com/ismellike)) +- Change / fix packages publishing order [\#769](https://github.com/CosmWasm/cw-plus/pull/769) ([maurolacy](https://github.com/maurolacy)) +- contracts: move schema gen boilerplate to a binary crate [\#760](https://github.com/CosmWasm/cw-plus/pull/760) ([uint](https://github.com/uint)) ## [v0.14.0](https://github.com/CosmWasm/cw-plus/tree/v0.14.0) (2022-07-27) From 712971d4163ef6d906e50168a13a6ffc2e57df3b Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Wed, 14 Sep 2022 15:31:27 +0200 Subject: [PATCH 454/631] Update optimizer to v0.12.8 --- .circleci/config.yml | 2 +- scripts/optimizer.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ccca8273f..75ba021d7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -736,7 +736,7 @@ jobs: - run: name: Build development contracts command: | - docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.6 + docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.8 docker cp with_code:/code/artifacts ./artifacts - run: name: Show data diff --git a/scripts/optimizer.sh b/scripts/optimizer.sh index 7bc022aef..5680828bc 100755 --- a/scripts/optimizer.sh +++ b/scripts/optimizer.sh @@ -1,7 +1,7 @@ : U="cosmwasm" -V="0.12.6" +V="0.12.8" M=$(uname -m) #M="x86_64" # Force Intel arch From 4a58a3a04ac8d1ba71ed43665b2b6c6750e451c1 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Fri, 16 Sep 2022 20:40:13 -0500 Subject: [PATCH 455/631] Make total a SnapshotItem --- contracts/cw4-group/src/contract.rs | 30 +++++++++++++++++------------ contracts/cw4-group/src/msg.rs | 2 +- contracts/cw4-group/src/state.rs | 20 +++++++++++++------ packages/cw4/src/lib.rs | 2 +- packages/cw4/src/query.rs | 4 +++- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 913d427f6..63ec3c2e8 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -53,7 +53,7 @@ pub fn create( let member_addr = deps.api.addr_validate(&member.addr)?; MEMBERS.save(deps.storage, &member_addr, &member.weight, height)?; } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total, height)?; Ok(()) } @@ -145,7 +145,7 @@ pub fn update_members( } } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total, height)?; Ok(MemberChangedHookMsg { diffs }) } @@ -157,20 +157,26 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { at_height: height, } => to_binary(&query_member(deps, addr, height)?), QueryMsg::ListMembers { start_after, limit } => { - to_binary(&list_members(deps, start_after, limit)?) + to_binary(&query_list_members(deps, start_after, limit)?) + } + QueryMsg::TotalWeight { at_height: height } => { + to_binary(&query_total_weight(deps, height)?) } - QueryMsg::TotalWeight {} => to_binary(&query_total_weight(deps)?), QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), QueryMsg::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?), } } -fn query_total_weight(deps: Deps) -> StdResult { - let weight = TOTAL.load(deps.storage)?; +pub fn query_total_weight(deps: Deps, height: Option) -> StdResult { + let weight = match height { + Some(h) => TOTAL.may_load_at_height(deps.storage, h), + None => TOTAL.may_load(deps.storage), + }? + .unwrap_or_default(); Ok(TotalWeightResponse { weight }) } -fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { +pub fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { let addr = deps.api.addr_validate(&addr)?; let weight = match height { Some(h) => MEMBERS.may_load_at_height(deps.storage, &addr, h), @@ -183,7 +189,7 @@ fn query_member(deps: Deps, addr: String, height: Option) -> StdResult, limit: Option, @@ -246,7 +252,7 @@ mod tests { let res = ADMIN.query_admin(deps.as_ref()).unwrap(); assert_eq!(Some(INIT_ADMIN.into()), res.admin); - let res = query_total_weight(deps.as_ref()).unwrap(); + let res = query_total_weight(deps.as_ref(), None).unwrap(); assert_eq!(17, res.weight); } @@ -264,7 +270,7 @@ mod tests { let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); assert_eq!(member3.weight, None); - let members = list_members(deps.as_ref(), None, None).unwrap(); + let members = query_list_members(deps.as_ref(), None, None).unwrap(); assert_eq!(members.members.len(), 2); // TODO: assert the set is proper } @@ -293,10 +299,10 @@ mod tests { let count = weights.iter().filter(|x| x.is_some()).count(); // TODO: more detailed compare? - let members = list_members(deps.as_ref(), None, None).unwrap(); + let members = query_list_members(deps.as_ref(), None, None).unwrap(); assert_eq!(count, members.members.len()); - let total = query_total_weight(deps.as_ref()).unwrap(); + let total = query_total_weight(deps.as_ref(), None).unwrap(); assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 } } diff --git a/contracts/cw4-group/src/msg.rs b/contracts/cw4-group/src/msg.rs index 823359ed2..3f9522749 100644 --- a/contracts/cw4-group/src/msg.rs +++ b/contracts/cw4-group/src/msg.rs @@ -31,7 +31,7 @@ pub enum QueryMsg { #[returns(cw_controllers::AdminResponse)] Admin {}, #[returns(cw4::TotalWeightResponse)] - TotalWeight {}, + TotalWeight { at_height: Option }, #[returns(cw4::MemberListResponse)] ListMembers { start_after: Option, diff --git a/contracts/cw4-group/src/state.rs b/contracts/cw4-group/src/state.rs index 1b5003c98..10497fa99 100644 --- a/contracts/cw4-group/src/state.rs +++ b/contracts/cw4-group/src/state.rs @@ -1,16 +1,24 @@ use cosmwasm_std::Addr; -use cw4::TOTAL_KEY; +use cw4::{ + MEMBERS_CHANGELOG, MEMBERS_CHECKPOINTS, MEMBERS_KEY, TOTAL_KEY, TOTAL_KEY_CHANGELOG, + TOTAL_KEY_CHECKPOINTS, +}; use cw_controllers::{Admin, Hooks}; -use cw_storage_plus::{Item, SnapshotMap, Strategy}; +use cw_storage_plus::{SnapshotItem, SnapshotMap, Strategy}; pub const ADMIN: Admin = Admin::new("admin"); pub const HOOKS: Hooks = Hooks::new("cw4-hooks"); -pub const TOTAL: Item = Item::new(TOTAL_KEY); +pub const TOTAL: SnapshotItem = SnapshotItem::new( + TOTAL_KEY, + TOTAL_KEY_CHECKPOINTS, + TOTAL_KEY_CHANGELOG, + Strategy::EveryBlock, +); pub const MEMBERS: SnapshotMap<&Addr, u64> = SnapshotMap::new( - cw4::MEMBERS_KEY, - cw4::MEMBERS_CHECKPOINTS, - cw4::MEMBERS_CHANGELOG, + MEMBERS_KEY, + MEMBERS_CHECKPOINTS, + MEMBERS_CHANGELOG, Strategy::EveryBlock, ); diff --git a/packages/cw4/src/lib.rs b/packages/cw4/src/lib.rs index 9185b6962..f57fd27d8 100644 --- a/packages/cw4/src/lib.rs +++ b/packages/cw4/src/lib.rs @@ -9,5 +9,5 @@ pub use crate::msg::Cw4ExecuteMsg; pub use crate::query::{ member_key, AdminResponse, Cw4QueryMsg, HooksResponse, Member, MemberListResponse, MemberResponse, TotalWeightResponse, MEMBERS_CHANGELOG, MEMBERS_CHECKPOINTS, MEMBERS_KEY, - TOTAL_KEY, + TOTAL_KEY, TOTAL_KEY_CHANGELOG, TOTAL_KEY_CHECKPOINTS, }; diff --git a/packages/cw4/src/query.rs b/packages/cw4/src/query.rs index 6745d6af1..c23f1fabe 100644 --- a/packages/cw4/src/query.rs +++ b/packages/cw4/src/query.rs @@ -6,7 +6,7 @@ pub enum Cw4QueryMsg { /// Return AdminResponse Admin {}, /// Return TotalWeightResponse - TotalWeight {}, + TotalWeight { at_height: Option }, /// Returns MembersListResponse ListMembers { start_after: Option, @@ -57,6 +57,8 @@ pub struct HooksResponse { /// TOTAL_KEY is meant for raw queries pub const TOTAL_KEY: &str = "total"; +pub const TOTAL_KEY_CHECKPOINTS: &str = "total__checkpoints"; +pub const TOTAL_KEY_CHANGELOG: &str = "total__changelog"; pub const MEMBERS_KEY: &str = "members"; pub const MEMBERS_CHECKPOINTS: &str = "members__checkpoints"; pub const MEMBERS_CHANGELOG: &str = "members__changelog"; From f8a287b6fa308212e4ddf9ad5c4143f5c1a9668e Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Fri, 16 Sep 2022 20:56:07 -0500 Subject: [PATCH 456/631] Safe math --- contracts/cw4-group/src/contract.rs | 21 +++++++++++---------- contracts/cw4-group/src/error.rs | 5 ++++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 63ec3c2e8..bde554ee7 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ attr, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, - SubMsg, + SubMsg, Uint64, }; use cw2::set_contract_version; use cw4::{ @@ -47,13 +47,14 @@ pub fn create( .transpose()?; ADMIN.set(deps.branch(), admin_addr)?; - let mut total = 0u64; + let mut total = Uint64::zero(); for member in members.into_iter() { - total += member.weight; + let member_weight = Uint64::from(member.weight); + total = total.checked_add(member_weight)?; let member_addr = deps.api.addr_validate(&member.addr)?; - MEMBERS.save(deps.storage, &member_addr, &member.weight, height)?; + MEMBERS.save(deps.storage, &member_addr, &member_weight.u64(), height)?; } - TOTAL.save(deps.storage, &total, height)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(()) } @@ -120,15 +121,15 @@ pub fn update_members( ) -> Result { ADMIN.assert_admin(deps.as_ref(), &sender)?; - let mut total = TOTAL.load(deps.storage)?; + let mut total = Uint64::from(TOTAL.load(deps.storage)?); let mut diffs: Vec = vec![]; // add all new members and update total for add in to_add.into_iter() { let add_addr = deps.api.addr_validate(&add.addr)?; MEMBERS.update(deps.storage, &add_addr, height, |old| -> StdResult<_> { - total -= old.unwrap_or_default(); - total += add.weight; + total = total.checked_sub(Uint64::from(old.unwrap_or_default()))?; + total = total.checked_add(Uint64::from(add.weight))?; diffs.push(MemberDiff::new(add.addr, old, Some(add.weight))); Ok(add.weight) })?; @@ -140,12 +141,12 @@ pub fn update_members( // Only process this if they were actually in the list before if let Some(weight) = old { diffs.push(MemberDiff::new(remove, Some(weight), None)); - total -= weight; + total = total.checked_sub(Uint64::from(weight))?; MEMBERS.remove(deps.storage, &remove_addr, height)?; } } - TOTAL.save(deps.storage, &total, height)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(MemberChangedHookMsg { diffs }) } diff --git a/contracts/cw4-group/src/error.rs b/contracts/cw4-group/src/error.rs index 82a84fe83..a5d2f57cf 100644 --- a/contracts/cw4-group/src/error.rs +++ b/contracts/cw4-group/src/error.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::StdError; +use cosmwasm_std::{OverflowError, StdError}; use thiserror::Error; use cw_controllers::{AdminError, HookError}; @@ -14,6 +14,9 @@ pub enum ContractError { #[error("{0}")] Admin(#[from] AdminError), + #[error("{0}")] + Overflow(#[from] OverflowError), + #[error("Unauthorized")] Unauthorized {}, } From 95344ee856b97d24aec62d0c1202f33d147b767e Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Sun, 18 Sep 2022 10:16:43 -0500 Subject: [PATCH 457/631] Move tests to proper module and add total_at_height test --- contracts/cw4-group/src/contract.rs | 349 -------------------------- contracts/cw4-group/src/lib.rs | 3 + contracts/cw4-group/src/tests.rs | 368 ++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+), 349 deletions(-) create mode 100644 contracts/cw4-group/src/tests.rs diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index bde554ee7..fe6270655 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -212,352 +212,3 @@ pub fn query_list_members( Ok(MemberListResponse { members }) } - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_slice, Api, OwnedDeps, Querier, Storage}; - use cw4::{member_key, TOTAL_KEY}; - use cw_controllers::{AdminError, HookError}; - - const INIT_ADMIN: &str = "juan"; - const USER1: &str = "somebody"; - const USER2: &str = "else"; - const USER3: &str = "funny"; - - fn do_instantiate(deps: DepsMut) { - let msg = InstantiateMsg { - admin: Some(INIT_ADMIN.into()), - members: vec![ - Member { - addr: USER1.into(), - weight: 11, - }, - Member { - addr: USER2.into(), - weight: 6, - }, - ], - }; - let info = mock_info("creator", &[]); - instantiate(deps, mock_env(), info, msg).unwrap(); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // it worked, let's query the state - let res = ADMIN.query_admin(deps.as_ref()).unwrap(); - assert_eq!(Some(INIT_ADMIN.into()), res.admin); - - let res = query_total_weight(deps.as_ref(), None).unwrap(); - assert_eq!(17, res.weight); - } - - #[test] - fn try_member_queries() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); - assert_eq!(member1.weight, Some(11)); - - let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); - assert_eq!(member2.weight, Some(6)); - - let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); - assert_eq!(member3.weight, None); - - let members = query_list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(members.members.len(), 2); - // TODO: assert the set is proper - } - - fn assert_users( - deps: &OwnedDeps, - user1_weight: Option, - user2_weight: Option, - user3_weight: Option, - height: Option, - ) { - let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); - assert_eq!(member1.weight, user1_weight); - - let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); - assert_eq!(member2.weight, user2_weight); - - let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); - assert_eq!(member3.weight, user3_weight); - - // this is only valid if we are not doing a historical query - if height.is_none() { - // compute expected metrics - let weights = vec![user1_weight, user2_weight, user3_weight]; - let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); - let count = weights.iter().filter(|x| x.is_some()).count(); - - // TODO: more detailed compare? - let members = query_list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(count, members.members.len()); - - let total = query_total_weight(deps.as_ref(), None).unwrap(); - assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 - } - } - - #[test] - fn add_new_remove_old_member() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER3.into(), - weight: 15, - }]; - let remove = vec![USER1.into()]; - - // non-admin cannot update - let height = mock_env().block.height; - let err = update_members( - deps.as_mut(), - height + 5, - Addr::unchecked(USER1), - add.clone(), - remove.clone(), - ) - .unwrap_err(); - assert_eq!(err, AdminError::NotAdmin {}.into()); - - // Test the values from instantiate - assert_users(&deps, Some(11), Some(6), None, None); - // Note all values were set at height, the beginning of that block was all None - assert_users(&deps, None, None, None, Some(height)); - // This will get us the values at the start of the block after instantiate (expected initial values) - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - - // admin updates properly - update_members( - deps.as_mut(), - height + 10, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - - // updated properly - assert_users(&deps, None, Some(6), Some(15), None); - - // snapshot still shows old value - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - } - - #[test] - fn add_old_remove_new_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER1.into(), - weight: 4, - }]; - let remove = vec![USER3.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, Some(4), Some(6), None, None); - } - - #[test] - fn add_and_remove_same_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER1.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, None, Some(6), Some(5), None); - } - - #[test] - fn add_remove_hooks() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - - // non-admin cannot add hook - let user_info = mock_info(USER1, &[]); - let err = execute( - deps.as_mut(), - mock_env(), - user_info.clone(), - add_msg.clone(), - ) - .unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // admin can add it, and it appears in the query - let admin_info = mock_info(INIT_ADMIN, &[]); - let _ = execute( - deps.as_mut(), - mock_env(), - admin_info.clone(), - add_msg.clone(), - ) - .unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone()]); - - // cannot remove a non-registered contract - let remove_msg = ExecuteMsg::RemoveHook { - addr: contract2.clone(), - }; - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); - assert_eq!(err, HookError::HookNotRegistered {}.into()); - - // add second contract - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); - - // cannot re-add an existing contract - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); - assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); - - // non-admin cannot remove - let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; - let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // remove the original - let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract2]); - } - - #[test] - fn hooks_fire() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - // register 2 hooks - let admin_info = mock_info(INIT_ADMIN, &[]); - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - for msg in vec![add_msg, add_msg2] { - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); - } - - // make some changes - add 3, remove 2, and update 1 - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER2.into()]; - let msg = ExecuteMsg::UpdateMembers { remove, add }; - - // admin updates properly - assert_users(&deps, Some(11), Some(6), None, None); - let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); - assert_users(&deps, Some(20), None, Some(5), None); - - // ensure 2 messages for the 2 hooks - assert_eq!(res.messages.len(), 2); - // same order as in the message (adds first, then remove) - let diffs = vec![ - MemberDiff::new(USER1, Some(11), Some(20)), - MemberDiff::new(USER3, None, Some(5)), - MemberDiff::new(USER2, Some(6), None), - ]; - let hook_msg = MemberChangedHookMsg { diffs }; - let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); - let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); - assert_eq!(res.messages, vec![msg1, msg2]); - } - - #[test] - fn raw_queries_work() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // get total from raw key - let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); - let total: u64 = from_slice(&total_raw).unwrap(); - assert_eq!(17, total); - - // get member votes from raw key - let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); - let member2: u64 = from_slice(&member2_raw).unwrap(); - assert_eq!(6, member2); - - // and execute misses - let member3_raw = deps.storage.get(&member_key(USER3)); - assert_eq!(None, member3_raw); - } -} diff --git a/contracts/cw4-group/src/lib.rs b/contracts/cw4-group/src/lib.rs index 98208b782..99fcca8b4 100644 --- a/contracts/cw4-group/src/lib.rs +++ b/contracts/cw4-group/src/lib.rs @@ -5,3 +5,6 @@ pub mod msg; pub mod state; pub use crate::error::ContractError; + +#[cfg(test)] +mod tests; diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs new file mode 100644 index 000000000..ca542efa1 --- /dev/null +++ b/contracts/cw4-group/src/tests.rs @@ -0,0 +1,368 @@ +use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::{from_slice, Addr, Api, DepsMut, OwnedDeps, Querier, Storage, SubMsg}; +use cw4::{member_key, Member, MemberChangedHookMsg, MemberDiff, TOTAL_KEY}; +use cw_controllers::{AdminError, HookError}; + +use crate::contract::{ + execute, instantiate, query_list_members, query_member, query_total_weight, update_members, +}; +use crate::msg::{ExecuteMsg, InstantiateMsg}; +use crate::state::{ADMIN, HOOKS}; + +const INIT_ADMIN: &str = "juan"; +const USER1: &str = "somebody"; +const USER2: &str = "else"; +const USER3: &str = "funny"; + +fn do_instantiate(deps: DepsMut) { + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ + Member { + addr: USER1.into(), + weight: 11, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + ], + }; + let info = mock_info("creator", &[]); + instantiate(deps, mock_env(), info, msg).unwrap(); +} + +#[test] +fn proper_instantiation() { + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + // it worked, let's query the state + let res = ADMIN.query_admin(deps.as_ref()).unwrap(); + assert_eq!(Some(INIT_ADMIN.into()), res.admin); + + let res = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, res.weight); +} + +#[test] +fn try_member_queries() { + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); + assert_eq!(member1.weight, Some(11)); + + let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); + assert_eq!(member2.weight, Some(6)); + + let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); + assert_eq!(member3.weight, None); + + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(members.members.len(), 2); + // TODO: assert the set is proper +} + +fn assert_users( + deps: &OwnedDeps, + user1_weight: Option, + user2_weight: Option, + user3_weight: Option, + height: Option, +) { + let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); + assert_eq!(member1.weight, user1_weight); + + let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); + assert_eq!(member2.weight, user2_weight); + + let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); + assert_eq!(member3.weight, user3_weight); + + // this is only valid if we are not doing a historical query + if height.is_none() { + // compute expected metrics + let weights = vec![user1_weight, user2_weight, user3_weight]; + let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); + let count = weights.iter().filter(|x| x.is_some()).count(); + + // TODO: more detailed compare? + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(count, members.members.len()); + + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 + } +} + +#[test] +fn add_new_remove_old_member() { + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER3.into(), + weight: 15, + }]; + let remove = vec![USER1.into()]; + + // non-admin cannot update + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(USER1), + add.clone(), + remove.clone(), + ) + .unwrap_err(); + assert_eq!(err, AdminError::NotAdmin {}.into()); + + // Test the values from instantiate + assert_users(&deps, Some(11), Some(6), None, None); + // Note all values were set at height, the beginning of that block was all None + assert_users(&deps, None, None, None, Some(height)); + // This will get us the values at the start of the block after instantiate (expected initial values) + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); + + // admin updates properly + update_members( + deps.as_mut(), + height + 10, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + + // updated properly + assert_users(&deps, None, Some(6), Some(15), None); + + // snapshot still shows old value + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); +} + +#[test] +fn add_old_remove_new_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER1.into(), + weight: 4, + }]; + let remove = vec![USER3.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, Some(4), Some(6), None, None); +} + +#[test] +fn add_and_remove_same_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER1.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, None, Some(6), Some(5), None); +} + +#[test] +fn add_remove_hooks() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + + // non-admin cannot add hook + let user_info = mock_info(USER1, &[]); + let err = execute( + deps.as_mut(), + mock_env(), + user_info.clone(), + add_msg.clone(), + ) + .unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // admin can add it, and it appears in the query + let admin_info = mock_info(INIT_ADMIN, &[]); + let _ = execute( + deps.as_mut(), + mock_env(), + admin_info.clone(), + add_msg.clone(), + ) + .unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone()]); + + // cannot remove a non-registered contract + let remove_msg = ExecuteMsg::RemoveHook { + addr: contract2.clone(), + }; + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); + assert_eq!(err, HookError::HookNotRegistered {}.into()); + + // add second contract + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); + + // cannot re-add an existing contract + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); + assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); + + // non-admin cannot remove + let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; + let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // remove the original + let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract2]); +} + +#[test] +fn hooks_fire() { + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + // register 2 hooks + let admin_info = mock_info(INIT_ADMIN, &[]); + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + for msg in vec![add_msg, add_msg2] { + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); + } + + // make some changes - add 3, remove 2, and update 1 + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER2.into()]; + let msg = ExecuteMsg::UpdateMembers { remove, add }; + + // admin updates properly + assert_users(&deps, Some(11), Some(6), None, None); + let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); + assert_users(&deps, Some(20), None, Some(5), None); + + // ensure 2 messages for the 2 hooks + assert_eq!(res.messages.len(), 2); + // same order as in the message (adds first, then remove) + let diffs = vec![ + MemberDiff::new(USER1, Some(11), Some(20)), + MemberDiff::new(USER3, None, Some(5)), + MemberDiff::new(USER2, Some(6), None), + ]; + let hook_msg = MemberChangedHookMsg { diffs }; + let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); + let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); + assert_eq!(res.messages, vec![msg1, msg2]); +} + +#[test] +fn raw_queries_work() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + // get total from raw key + let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); + let total: u64 = from_slice(&total_raw).unwrap(); + assert_eq!(17, total); + + // get member votes from raw key + let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); + let member2: u64 = from_slice(&member2_raw).unwrap(); + assert_eq!(6, member2); + + // and execute misses + let member3_raw = deps.storage.get(&member_key(USER3)); + assert_eq!(None, member3_raw); +} + +#[test] +fn total_at_height() { + let mut deps = mock_dependencies(); + do_instantiate(deps.as_mut()); + + let height = mock_env().block.height; + + // Test the values from instantiate + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, total.weight); + // Note all values were set at height, the beginning of that block was all None + let total = query_total_weight(deps.as_ref(), Some(height)).unwrap(); + assert_eq!(0, total.weight); + // This will get us the values at the start of the block after instantiate (expected initial values) + let total = query_total_weight(deps.as_ref(), Some(height + 1)).unwrap(); + assert_eq!(17, total.weight); +} From 435438c2d8e5b6c56e8912ae06b9063409d34105 Mon Sep 17 00:00:00 2001 From: Manuel Turetta Date: Fri, 16 Sep 2022 18:40:54 +0200 Subject: [PATCH 458/631] Add clear method to Map --- packages/storage-plus/src/map.rs | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 4dcc5398b..4ba02f908 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -260,6 +260,33 @@ where } } +#[cfg(feature = "iterator")] +impl<'a, K, T> Map<'a, K, T> +where + T: Serialize + DeserializeOwned, + K: PrimaryKey<'a>, +{ + /// Clears the map, removing all elements. + pub fn clear(&self, store: &mut dyn Storage) { + const TAKE: usize = 10; + let prefix = self.no_prefix_raw(); + let mut cleared = false; + + while !cleared { + let paths = prefix + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .map(|raw_key| Path::::new(self.namespace, &[raw_key.as_slice()])) + // Take just TAKE elements to prevent possible heap overflow if the Map is big. + .take(TAKE) + .collect::>(); + + paths.iter().for_each(|path| store.remove(path)); + + cleared = paths.len() < TAKE; + } + } +} + #[cfg(test)] mod test { use super::*; @@ -1511,4 +1538,25 @@ mod test { assert_eq!(include.len(), 1); assert_eq!(include, vec![456]); } + + #[test] + #[cfg(feature = "iterator")] + fn clear() { + const TEST_MAP: Map<&str, u32> = Map::new("test_map"); + + let mut storage = MockStorage::new(); + TEST_MAP.save(&mut storage, "key0", &0u32).unwrap(); + TEST_MAP.save(&mut storage, "key1", &1u32).unwrap(); + TEST_MAP.save(&mut storage, "key2", &2u32).unwrap(); + TEST_MAP.save(&mut storage, "key3", &3u32).unwrap(); + TEST_MAP.save(&mut storage, "key4", &4u32).unwrap(); + + TEST_MAP.clear(&mut storage); + + assert!(!TEST_MAP.has(&mut storage, "key0")); + assert!(!TEST_MAP.has(&mut storage, "key1")); + assert!(!TEST_MAP.has(&mut storage, "key2")); + assert!(!TEST_MAP.has(&mut storage, "key3")); + assert!(!TEST_MAP.has(&mut storage, "key4")); + } } From 25a6a701179080196130ac025cafbd2a37dab98a Mon Sep 17 00:00:00 2001 From: Manuel Turetta Date: Mon, 19 Sep 2022 14:16:23 +0200 Subject: [PATCH 459/631] Add is_empty method to Map --- packages/storage-plus/src/map.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 4ba02f908..b5d4730dd 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -285,6 +285,14 @@ where cleared = paths.len() < TAKE; } } + + /// Returns `true` if the map is empty. + pub fn is_empty(&self, store: &dyn Storage) -> bool { + self.no_prefix_raw() + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .next() + .is_none() + } } #[cfg(test)] @@ -1541,7 +1549,7 @@ mod test { #[test] #[cfg(feature = "iterator")] - fn clear() { + fn clear_works() { const TEST_MAP: Map<&str, u32> = Map::new("test_map"); let mut storage = MockStorage::new(); @@ -1559,4 +1567,19 @@ mod test { assert!(!TEST_MAP.has(&mut storage, "key3")); assert!(!TEST_MAP.has(&mut storage, "key4")); } + + #[test] + #[cfg(feature = "iterator")] + fn is_empty_works() { + const TEST_MAP: Map<&str, u32> = Map::new("test_map"); + + let mut storage = MockStorage::new(); + + assert!(TEST_MAP.is_empty(&storage)); + + TEST_MAP.save(&mut storage, "key1", &1u32).unwrap(); + TEST_MAP.save(&mut storage, "key2", &2u32).unwrap(); + + assert!(!TEST_MAP.is_empty(&storage)); + } } From 34dfdf7bd41cded8d3a06a2823b6a99a118d41b2 Mon Sep 17 00:00:00 2001 From: Manuel Turetta Date: Mon, 19 Sep 2022 15:08:26 +0200 Subject: [PATCH 460/631] Fix lint errors --- packages/storage-plus/src/map.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index b5d4730dd..237861e90 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -1561,11 +1561,11 @@ mod test { TEST_MAP.clear(&mut storage); - assert!(!TEST_MAP.has(&mut storage, "key0")); - assert!(!TEST_MAP.has(&mut storage, "key1")); - assert!(!TEST_MAP.has(&mut storage, "key2")); - assert!(!TEST_MAP.has(&mut storage, "key3")); - assert!(!TEST_MAP.has(&mut storage, "key4")); + assert!(!TEST_MAP.has(&storage, "key0")); + assert!(!TEST_MAP.has(&storage, "key1")); + assert!(!TEST_MAP.has(&storage, "key2")); + assert!(!TEST_MAP.has(&storage, "key3")); + assert!(!TEST_MAP.has(&storage, "key4")); } #[test] From 965c8b9499047e5a1ae10529e1e495a4c177ed09 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 20 Sep 2022 02:52:28 -0500 Subject: [PATCH 461/631] Use public queries and move tests --- contracts/cw1155-base/src/contract.rs | 824 +++----------------------- contracts/cw1155-base/src/lib.rs | 3 + contracts/cw1155-base/src/tests.rs | 694 ++++++++++++++++++++++ 3 files changed, 780 insertions(+), 741 deletions(-) create mode 100644 contracts/cw1155-base/src/tests.rs diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 5add6b405..425609119 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -1,22 +1,21 @@ -use cosmwasm_std::entry_point; +use crate::{ + error::ContractError, + msg::InstantiateMsg, + state::{APPROVES, BALANCES, MINTER, TOKENS}, +}; use cosmwasm_std::{ - to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, SubMsg, - Uint128, + entry_point, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, + StdResult, SubMsg, Uint128, }; -use cw_storage_plus::Bound; - use cw1155::{ ApproveAllEvent, ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, Cw1155BatchReceiveMsg, Cw1155ExecuteMsg, Cw1155QueryMsg, Cw1155ReceiveMsg, Expiration, IsApprovedForAllResponse, TokenId, TokenInfoResponse, TokensResponse, TransferEvent, }; use cw2::set_contract_version; +use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Event}; -use crate::error::ContractError; -use crate::msg::InstantiateMsg; -use crate::state::{APPROVES, BALANCES, MINTER, TOKENS}; - // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw1155-base"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -419,65 +418,68 @@ pub fn execute_revoke_all(env: ExecuteEnv, operator: String) -> Result StdResult { match msg { Cw1155QueryMsg::Balance { owner, token_id } => { - let owner_addr = deps.api.addr_validate(&owner)?; - let balance = BALANCES - .may_load(deps.storage, (&owner_addr, &token_id))? - .unwrap_or_default(); - to_binary(&BalanceResponse { balance }) + to_binary(&query_balance(deps, owner, token_id)?) } Cw1155QueryMsg::BatchBalance { owner, token_ids } => { - let owner_addr = deps.api.addr_validate(&owner)?; - let balances = token_ids - .into_iter() - .map(|token_id| -> StdResult<_> { - Ok(BALANCES - .may_load(deps.storage, (&owner_addr, &token_id))? - .unwrap_or_default()) - }) - .collect::>()?; - to_binary(&BatchBalanceResponse { balances }) + to_binary(&query_batch_balance(deps, owner, token_ids)?) } Cw1155QueryMsg::IsApprovedForAll { owner, operator } => { - let owner_addr = deps.api.addr_validate(&owner)?; - let operator_addr = deps.api.addr_validate(&operator)?; - let approved = check_can_approve(deps, &env, &owner_addr, &operator_addr)?; - to_binary(&IsApprovedForAllResponse { approved }) + to_binary(&query_is_approved_for_all(deps, env, owner, operator)?) } Cw1155QueryMsg::ApprovedForAll { owner, include_expired, start_after, limit, - } => { - let owner_addr = deps.api.addr_validate(&owner)?; - let start_addr = maybe_addr(deps.api, start_after)?; - to_binary(&query_all_approvals( - deps, - env, - owner_addr, - include_expired.unwrap_or(false), - start_addr, - limit, - )?) - } - Cw1155QueryMsg::TokenInfo { token_id } => { - let url = TOKENS.load(deps.storage, &token_id)?; - to_binary(&TokenInfoResponse { url }) - } + } => to_binary(&query_approved_for_all( + deps, + env, + owner, + include_expired.unwrap_or(false), + start_after, + limit, + )?), + Cw1155QueryMsg::TokenInfo { token_id } => to_binary(&query_token_info(deps, token_id)?), Cw1155QueryMsg::Tokens { owner, start_after, limit, - } => { - let owner_addr = deps.api.addr_validate(&owner)?; - to_binary(&query_tokens(deps, owner_addr, start_after, limit)?) - } + } => to_binary(&query_tokens(deps, owner, start_after, limit)?), Cw1155QueryMsg::AllTokens { start_after, limit } => { to_binary(&query_all_tokens(deps, start_after, limit)?) } } } +pub fn query_balance(deps: Deps, owner: String, token_id: String) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + + let balance = BALANCES + .may_load(deps.storage, (&owner, &token_id))? + .unwrap_or_default(); + + Ok(BalanceResponse { balance }) +} + +pub fn query_batch_balance( + deps: Deps, + owner: String, + token_ids: Vec, +) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + + let balances = token_ids + .into_iter() + .map(|token_id| -> StdResult<_> { + Ok(BALANCES + .may_load(deps.storage, (&owner, &token_id))? + .unwrap_or_default()) + }) + .collect::>()?; + + Ok(BatchBalanceResponse { balances }) +} + fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult { item.map(|(addr, expires)| cw1155::Approval { spender: addr.into(), @@ -485,14 +487,16 @@ fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult, + start_after: Option, limit: Option, ) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + let start_after = maybe_addr(deps.api, start_after)?; let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.as_ref().map(Bound::exclusive); @@ -503,15 +507,37 @@ fn query_all_approvals( .take(limit) .map(build_approval) .collect::>()?; + Ok(ApprovedForAllResponse { operators }) } -fn query_tokens( +pub fn query_token_info(deps: Deps, token_id: String) -> StdResult { + let url = TOKENS.load(deps.storage, &token_id)?; + + Ok(TokenInfoResponse { url }) +} + +pub fn query_is_approved_for_all( deps: Deps, - owner: Addr, + env: Env, + owner: String, + operator: String, +) -> StdResult { + let owner_addr = deps.api.addr_validate(&owner)?; + let operator_addr = deps.api.addr_validate(&operator)?; + + let approved = check_can_approve(deps, &env, &owner_addr, &operator_addr)?; + + Ok(IsApprovedForAllResponse { approved }) +} + +pub fn query_tokens( + deps: Deps, + owner: String, start_after: Option, limit: Option, ) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); @@ -520,706 +546,22 @@ fn query_tokens( .keys(deps.storage, start, None, Order::Ascending) .take(limit) .collect::>()?; + Ok(TokensResponse { tokens }) } -fn query_all_tokens( +pub fn query_all_tokens( deps: Deps, start_after: Option, limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; 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) .collect::>()?; - Ok(TokensResponse { tokens }) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{OverflowError, StdError}; - - use super::*; - - #[test] - fn check_transfers() { - // A long test case that try to cover as many cases as possible. - // Summary of what it does: - // - try mint without permission, fail - // - mint with permission, success - // - query balance of receipant, success - // - try transfer without approval, fail - // - approve - // - transfer again, success - // - query balance of transfer participants - // - batch mint token2 and token3, success - // - try batch transfer without approval, fail - // - approve and try batch transfer again, success - // - batch query balances - // - user1 revoke approval to minter - // - query approval status - // - minter try to transfer, fail - // - user1 burn token1 - // - user1 batch burn token2 and token3 - let token1 = "token1".to_owned(); - let token2 = "token2".to_owned(); - let token3 = "token3".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let user2 = String::from("user2"); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // invalid mint, user1 don't mint permission - let mint_msg = Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }; - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - mint_msg.clone(), - ), - Err(ContractError::Unauthorized {}) - )); - - // valid mint - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - mint_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user1) - ); - - // query balance - assert_eq!( - to_binary(&BalanceResponse { - balance: 1u64.into() - }), - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user1.clone(), - token_id: token1.clone(), - } - ), - ); - - let transfer_msg = Cw1155ExecuteMsg::SendFrom { - from: user1.clone(), - to: user2.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }; - - // not approved yet - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - transfer_msg.clone(), - ), - Err(ContractError::Unauthorized {}) - )); - - // approve - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: minter.clone(), - expires: None, - }, - ) - .unwrap(); - - // transfer - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - transfer_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("to", &user2) - ); - - // query balance - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user2.clone(), - token_id: token1.clone(), - } - ), - to_binary(&BalanceResponse { - balance: 1u64.into() - }), - ); - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user1.clone(), - token_id: token1.clone(), - } - ), - to_binary(&BalanceResponse { - balance: 0u64.into() - }), - ); - - // batch mint token2 and token3 - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::BatchMint { - to: user2.clone(), - batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())], - msg: None - }, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user2) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user2) - ); - - // invalid batch transfer, (user2 not approved yet) - let batch_transfer_msg = Cw1155ExecuteMsg::BatchSendFrom { - from: user2.clone(), - to: user1.clone(), - batch: vec![ - (token1.clone(), 1u64.into()), - (token2.clone(), 1u64.into()), - (token3.clone(), 1u64.into()), - ], - msg: None, - }; - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - batch_transfer_msg.clone(), - ), - Err(ContractError::Unauthorized {}), - )); - - // user2 approve - execute( - deps.as_mut(), - mock_env(), - mock_info(user2.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: minter.clone(), - expires: None, - }, - ) - .unwrap(); - - // valid batch transfer - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - batch_transfer_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - ); - - // batch query - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::BatchBalance { - owner: user1.clone(), - token_ids: vec![token1.clone(), token2.clone(), token3.clone()], - } - ), - to_binary(&BatchBalanceResponse { - balances: vec![1u64.into(), 1u64.into(), 1u64.into()] - }), - ); - - // user1 revoke approval - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::RevokeAll { - operator: minter.clone(), - }, - ) - .unwrap(); - - // query approval status - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::IsApprovedForAll { - owner: user1.clone(), - operator: minter.clone(), - } - ), - to_binary(&IsApprovedForAllResponse { approved: false }), - ); - - // tranfer without approval - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::SendFrom { - from: user1.clone(), - to: user2, - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }, - ), - Err(ContractError::Unauthorized {}) - )); - - // burn token1 - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::Burn { - from: user1.clone(), - token_id: token1.clone(), - value: 1u64.into(), - } - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - ); - - // burn them all - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::BatchBurn { - from: user1.clone(), - batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())] - } - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - ); - } - - #[test] - fn check_send_contract() { - let receiver = String::from("receive_contract"); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let token1 = "token1".to_owned(); - let token2 = "token2".to_owned(); - let dummy_msg = Binary::default(); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token2.clone(), - value: 1u64.into(), - msg: None, - }, - ) - .unwrap(); - - // mint to contract - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: receiver.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: Some(dummy_msg.clone()), - }, - ) - .unwrap(), - Response::new() - .add_message( - Cw1155ReceiveMsg { - operator: minter.clone(), - from: None, - amount: 1u64.into(), - token_id: token1.clone(), - msg: dummy_msg.clone(), - } - .into_cosmos_msg(receiver.clone()) - .unwrap() - ) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &receiver) - ); - - // BatchSendFrom - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::BatchSendFrom { - from: user1.clone(), - to: receiver.clone(), - batch: vec![(token2.clone(), 1u64.into())], - msg: Some(dummy_msg.clone()), - }, - ) - .unwrap(), - Response::new() - .add_message( - Cw1155BatchReceiveMsg { - operator: user1.clone(), - from: Some(user1.clone()), - batch: vec![(token2.clone(), 1u64.into())], - msg: dummy_msg, - } - .into_cosmos_msg(receiver.clone()) - .unwrap() - ) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("to", &receiver) - ); - } - - #[test] - fn check_queries() { - // mint multiple types of tokens, and query them - // grant approval to multiple operators, and query them - let tokens = (0..10).map(|i| format!("token{}", i)).collect::>(); - let users = (0..10).map(|i| format!("user{}", i)).collect::>(); - let minter = String::from("minter"); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::BatchMint { - to: users[0].clone(), - batch: tokens - .iter() - .map(|token_id| (token_id.clone(), 1u64.into())) - .collect::>(), - msg: None, - }, - ) - .unwrap(); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Tokens { - owner: users[0].clone(), - start_after: None, - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[..5].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Tokens { - owner: users[0].clone(), - start_after: Some("token5".to_owned()), - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[6..].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::AllTokens { - start_after: Some("token5".to_owned()), - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[6..].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::TokenInfo { - token_id: "token5".to_owned() - }, - ), - to_binary(&TokenInfoResponse { url: "".to_owned() }) - ); - - for user in users[1..].iter() { - execute( - deps.as_mut(), - mock_env(), - mock_info(users[0].as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user.clone(), - expires: None, - }, - ) - .unwrap(); - } - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::ApprovedForAll { - owner: users[0].clone(), - include_expired: None, - start_after: Some(String::from("user2")), - limit: Some(1), - }, - ), - to_binary(&ApprovedForAllResponse { - operators: vec![cw1155::Approval { - spender: users[3].clone(), - expires: Expiration::Never {} - }], - }) - ); - } - #[test] - fn approval_expires() { - let mut deps = mock_dependencies(); - let token1 = "token1".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let user2 = String::from("user2"); - - let env = { - let mut env = mock_env(); - env.block.height = 10; - env - }; - - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - env.clone(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1, - value: 1u64.into(), - msg: None, - }, - ) - .unwrap(); - - // invalid expires should be rejected - assert!(matches!( - execute( - deps.as_mut(), - env.clone(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user2.clone(), - expires: Some(Expiration::AtHeight(5)), - }, - ), - Err(_) - )); - - execute( - deps.as_mut(), - env.clone(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user2.clone(), - expires: Some(Expiration::AtHeight(100)), - }, - ) - .unwrap(); - - let query_msg = Cw1155QueryMsg::IsApprovedForAll { - owner: user1, - operator: user2, - }; - assert_eq!( - query(deps.as_ref(), env, query_msg.clone()), - to_binary(&IsApprovedForAllResponse { approved: true }) - ); - - let env = { - let mut env = mock_env(); - env.block.height = 100; - env - }; - - assert_eq!( - query(deps.as_ref(), env, query_msg,), - to_binary(&IsApprovedForAllResponse { approved: false }) - ); - } - - #[test] - fn mint_overflow() { - let mut deps = mock_dependencies(); - let token1 = "token1".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - - let env = mock_env(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - env.clone(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1.clone(), - value: u128::MAX.into(), - msg: None, - }, - ) - .unwrap(); - - assert!(matches!( - execute( - deps.as_mut(), - env, - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1, - token_id: token1, - value: 1u64.into(), - msg: None, - }, - ), - Err(ContractError::Std(StdError::Overflow { - source: OverflowError { .. }, - .. - })) - )); - } + Ok(TokensResponse { tokens }) } diff --git a/contracts/cw1155-base/src/lib.rs b/contracts/cw1155-base/src/lib.rs index dfedc9dc6..69b809fe1 100644 --- a/contracts/cw1155-base/src/lib.rs +++ b/contracts/cw1155-base/src/lib.rs @@ -4,3 +4,6 @@ pub mod msg; pub mod state; pub use crate::error::ContractError; + +#[cfg(test)] +mod tests; diff --git a/contracts/cw1155-base/src/tests.rs b/contracts/cw1155-base/src/tests.rs new file mode 100644 index 000000000..6202bdef8 --- /dev/null +++ b/contracts/cw1155-base/src/tests.rs @@ -0,0 +1,694 @@ +use crate::{ + contract::{execute, instantiate, query}, + msg::InstantiateMsg, + ContractError, +}; +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_binary, Binary, OverflowError, Response, StdError, +}; +use cw1155::{ + ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, Cw1155BatchReceiveMsg, + Cw1155ExecuteMsg, Cw1155QueryMsg, Cw1155ReceiveMsg, IsApprovedForAllResponse, + TokenInfoResponse, TokensResponse, +}; +use cw_utils::Expiration; + +#[test] +fn check_transfers() { + // A long test case that try to cover as many cases as possible. + // Summary of what it does: + // - try mint without permission, fail + // - mint with permission, success + // - query balance of receipant, success + // - try transfer without approval, fail + // - approve + // - transfer again, success + // - query balance of transfer participants + // - batch mint token2 and token3, success + // - try batch transfer without approval, fail + // - approve and try batch transfer again, success + // - batch query balances + // - user1 revoke approval to minter + // - query approval status + // - minter try to transfer, fail + // - user1 burn token1 + // - user1 batch burn token2 and token3 + let token1 = "token1".to_owned(); + let token2 = "token2".to_owned(); + let token3 = "token3".to_owned(); + let minter = String::from("minter"); + let user1 = String::from("user1"); + let user2 = String::from("user2"); + + let mut deps = mock_dependencies(); + let msg = InstantiateMsg { + minter: minter.clone(), + }; + let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // invalid mint, user1 don't mint permission + let mint_msg = Cw1155ExecuteMsg::Mint { + to: user1.clone(), + token_id: token1.clone(), + value: 1u64.into(), + msg: None, + }; + assert!(matches!( + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + mint_msg.clone(), + ), + Err(ContractError::Unauthorized {}) + )); + + // valid mint + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + mint_msg, + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token1) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("to", &user1) + ); + + // query balance + assert_eq!( + to_binary(&BalanceResponse { + balance: 1u64.into() + }), + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::Balance { + owner: user1.clone(), + token_id: token1.clone(), + } + ), + ); + + let transfer_msg = Cw1155ExecuteMsg::SendFrom { + from: user1.clone(), + to: user2.clone(), + token_id: token1.clone(), + value: 1u64.into(), + msg: None, + }; + + // not approved yet + assert!(matches!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + transfer_msg.clone(), + ), + Err(ContractError::Unauthorized {}) + )); + + // approve + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::ApproveAll { + operator: minter.clone(), + expires: None, + }, + ) + .unwrap(); + + // transfer + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + transfer_msg, + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token1) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user1) + .add_attribute("to", &user2) + ); + + // query balance + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::Balance { + owner: user2.clone(), + token_id: token1.clone(), + } + ), + to_binary(&BalanceResponse { + balance: 1u64.into() + }), + ); + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::Balance { + owner: user1.clone(), + token_id: token1.clone(), + } + ), + to_binary(&BalanceResponse { + balance: 0u64.into() + }), + ); + + // batch mint token2 and token3 + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::BatchMint { + to: user2.clone(), + batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())], + msg: None + }, + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token2) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("to", &user2) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token3) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("to", &user2) + ); + + // invalid batch transfer, (user2 not approved yet) + let batch_transfer_msg = Cw1155ExecuteMsg::BatchSendFrom { + from: user2.clone(), + to: user1.clone(), + batch: vec![ + (token1.clone(), 1u64.into()), + (token2.clone(), 1u64.into()), + (token3.clone(), 1u64.into()), + ], + msg: None, + }; + assert!(matches!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + batch_transfer_msg.clone(), + ), + Err(ContractError::Unauthorized {}), + )); + + // user2 approve + execute( + deps.as_mut(), + mock_env(), + mock_info(user2.as_ref(), &[]), + Cw1155ExecuteMsg::ApproveAll { + operator: minter.clone(), + expires: None, + }, + ) + .unwrap(); + + // valid batch transfer + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + batch_transfer_msg, + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token1) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user2) + .add_attribute("to", &user1) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token2) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user2) + .add_attribute("to", &user1) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token3) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user2) + .add_attribute("to", &user1) + ); + + // batch query + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::BatchBalance { + owner: user1.clone(), + token_ids: vec![token1.clone(), token2.clone(), token3.clone()], + } + ), + to_binary(&BatchBalanceResponse { + balances: vec![1u64.into(), 1u64.into(), 1u64.into()] + }), + ); + + // user1 revoke approval + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::RevokeAll { + operator: minter.clone(), + }, + ) + .unwrap(); + + // query approval status + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::IsApprovedForAll { + owner: user1.clone(), + operator: minter.clone(), + } + ), + to_binary(&IsApprovedForAllResponse { approved: false }), + ); + + // tranfer without approval + assert!(matches!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::SendFrom { + from: user1.clone(), + to: user2, + token_id: token1.clone(), + value: 1u64.into(), + msg: None, + }, + ), + Err(ContractError::Unauthorized {}) + )); + + // burn token1 + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::Burn { + from: user1.clone(), + token_id: token1.clone(), + value: 1u64.into(), + } + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token1) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user1) + ); + + // burn them all + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::BatchBurn { + from: user1.clone(), + batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())] + } + ) + .unwrap(), + Response::new() + .add_attribute("action", "transfer") + .add_attribute("token_id", &token2) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user1) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token3) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user1) + ); +} + +#[test] +fn check_send_contract() { + let receiver = String::from("receive_contract"); + let minter = String::from("minter"); + let user1 = String::from("user1"); + let token1 = "token1".to_owned(); + let token2 = "token2".to_owned(); + let dummy_msg = Binary::default(); + + let mut deps = mock_dependencies(); + let msg = InstantiateMsg { + minter: minter.clone(), + }; + let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::Mint { + to: user1.clone(), + token_id: token2.clone(), + value: 1u64.into(), + msg: None, + }, + ) + .unwrap(); + + // mint to contract + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::Mint { + to: receiver.clone(), + token_id: token1.clone(), + value: 1u64.into(), + msg: Some(dummy_msg.clone()), + }, + ) + .unwrap(), + Response::new() + .add_message( + Cw1155ReceiveMsg { + operator: minter.clone(), + from: None, + amount: 1u64.into(), + token_id: token1.clone(), + msg: dummy_msg.clone(), + } + .into_cosmos_msg(receiver.clone()) + .unwrap() + ) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token1) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("to", &receiver) + ); + + // BatchSendFrom + assert_eq!( + execute( + deps.as_mut(), + mock_env(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::BatchSendFrom { + from: user1.clone(), + to: receiver.clone(), + batch: vec![(token2.clone(), 1u64.into())], + msg: Some(dummy_msg.clone()), + }, + ) + .unwrap(), + Response::new() + .add_message( + Cw1155BatchReceiveMsg { + operator: user1.clone(), + from: Some(user1.clone()), + batch: vec![(token2.clone(), 1u64.into())], + msg: dummy_msg, + } + .into_cosmos_msg(receiver.clone()) + .unwrap() + ) + .add_attribute("action", "transfer") + .add_attribute("token_id", &token2) + .add_attribute("amount", 1u64.to_string()) + .add_attribute("from", &user1) + .add_attribute("to", &receiver) + ); +} + +#[test] +fn check_queries() { + // mint multiple types of tokens, and query them + // grant approval to multiple operators, and query them + let tokens = (0..10).map(|i| format!("token{}", i)).collect::>(); + let users = (0..10).map(|i| format!("user{}", i)).collect::>(); + let minter = String::from("minter"); + + let mut deps = mock_dependencies(); + let msg = InstantiateMsg { + minter: minter.clone(), + }; + let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + execute( + deps.as_mut(), + mock_env(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::BatchMint { + to: users[0].clone(), + batch: tokens + .iter() + .map(|token_id| (token_id.clone(), 1u64.into())) + .collect::>(), + msg: None, + }, + ) + .unwrap(); + + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::Tokens { + owner: users[0].clone(), + start_after: None, + limit: Some(5), + }, + ), + to_binary(&TokensResponse { + tokens: tokens[..5].to_owned() + }) + ); + + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::Tokens { + owner: users[0].clone(), + start_after: Some("token5".to_owned()), + limit: Some(5), + }, + ), + to_binary(&TokensResponse { + tokens: tokens[6..].to_owned() + }) + ); + + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::AllTokens { + start_after: Some("token5".to_owned()), + limit: Some(5), + }, + ), + to_binary(&TokensResponse { + tokens: tokens[6..].to_owned() + }) + ); + + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::TokenInfo { + token_id: "token5".to_owned() + }, + ), + to_binary(&TokenInfoResponse { url: "".to_owned() }) + ); + + for user in users[1..].iter() { + execute( + deps.as_mut(), + mock_env(), + mock_info(users[0].as_ref(), &[]), + Cw1155ExecuteMsg::ApproveAll { + operator: user.clone(), + expires: None, + }, + ) + .unwrap(); + } + + assert_eq!( + query( + deps.as_ref(), + mock_env(), + Cw1155QueryMsg::ApprovedForAll { + owner: users[0].clone(), + include_expired: None, + start_after: Some(String::from("user2")), + limit: Some(1), + }, + ), + to_binary(&ApprovedForAllResponse { + operators: vec![cw1155::Approval { + spender: users[3].clone(), + expires: Expiration::Never {} + }], + }) + ); +} + +#[test] +fn approval_expires() { + let mut deps = mock_dependencies(); + let token1 = "token1".to_owned(); + let minter = String::from("minter"); + let user1 = String::from("user1"); + let user2 = String::from("user2"); + + let env = { + let mut env = mock_env(); + env.block.height = 10; + env + }; + + let msg = InstantiateMsg { + minter: minter.clone(), + }; + let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + execute( + deps.as_mut(), + env.clone(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::Mint { + to: user1.clone(), + token_id: token1, + value: 1u64.into(), + msg: None, + }, + ) + .unwrap(); + + // invalid expires should be rejected + assert!(matches!( + execute( + deps.as_mut(), + env.clone(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::ApproveAll { + operator: user2.clone(), + expires: Some(Expiration::AtHeight(5)), + }, + ), + Err(_) + )); + + execute( + deps.as_mut(), + env.clone(), + mock_info(user1.as_ref(), &[]), + Cw1155ExecuteMsg::ApproveAll { + operator: user2.clone(), + expires: Some(Expiration::AtHeight(100)), + }, + ) + .unwrap(); + + let query_msg = Cw1155QueryMsg::IsApprovedForAll { + owner: user1, + operator: user2, + }; + assert_eq!( + query(deps.as_ref(), env, query_msg.clone()), + to_binary(&IsApprovedForAllResponse { approved: true }) + ); + + let env = { + let mut env = mock_env(); + env.block.height = 100; + env + }; + + assert_eq!( + query(deps.as_ref(), env, query_msg,), + to_binary(&IsApprovedForAllResponse { approved: false }) + ); +} + +#[test] +fn mint_overflow() { + let mut deps = mock_dependencies(); + let token1 = "token1".to_owned(); + let minter = String::from("minter"); + let user1 = String::from("user1"); + + let env = mock_env(); + let msg = InstantiateMsg { + minter: minter.clone(), + }; + let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + execute( + deps.as_mut(), + env.clone(), + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::Mint { + to: user1.clone(), + token_id: token1.clone(), + value: u128::MAX.into(), + msg: None, + }, + ) + .unwrap(); + + assert!(matches!( + execute( + deps.as_mut(), + env, + mock_info(minter.as_ref(), &[]), + Cw1155ExecuteMsg::Mint { + to: user1, + token_id: token1, + value: 1u64.into(), + msg: None, + }, + ), + Err(ContractError::Std(StdError::Overflow { + source: OverflowError { .. }, + .. + })) + )); +} From 90db17231e15eef99b2dbacd80793859fcab072a Mon Sep 17 00:00:00 2001 From: Manuel Turetta Date: Mon, 26 Sep 2022 23:35:19 +0200 Subject: [PATCH 462/631] Apply review suggestions --- packages/storage-plus/src/map.rs | 65 +++++++++++++++----------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs index 237861e90..322cdeec7 100644 --- a/packages/storage-plus/src/map.rs +++ b/packages/storage-plus/src/map.rs @@ -109,6 +109,36 @@ where from_slice(&result).map(Some) } } + + /// Clears the map, removing all elements. + #[cfg(feature = "iterator")] + pub fn clear(&self, store: &mut dyn Storage) { + const TAKE: usize = 10; + let mut cleared = false; + + while !cleared { + let paths = self + .no_prefix_raw() + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .map(|raw_key| Path::::new(self.namespace, &[raw_key.as_slice()])) + // Take just TAKE elements to prevent possible heap overflow if the Map is big. + .take(TAKE) + .collect::>(); + + paths.iter().for_each(|path| store.remove(path)); + + cleared = paths.len() < TAKE; + } + } + + /// Returns `true` if the map is empty. + #[cfg(feature = "iterator")] + pub fn is_empty(&self, store: &dyn Storage) -> bool { + self.no_prefix_raw() + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .next() + .is_none() + } } #[cfg(feature = "iterator")] @@ -260,41 +290,6 @@ where } } -#[cfg(feature = "iterator")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a>, -{ - /// Clears the map, removing all elements. - pub fn clear(&self, store: &mut dyn Storage) { - const TAKE: usize = 10; - let prefix = self.no_prefix_raw(); - let mut cleared = false; - - while !cleared { - let paths = prefix - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .map(|raw_key| Path::::new(self.namespace, &[raw_key.as_slice()])) - // Take just TAKE elements to prevent possible heap overflow if the Map is big. - .take(TAKE) - .collect::>(); - - paths.iter().for_each(|path| store.remove(path)); - - cleared = paths.len() < TAKE; - } - } - - /// Returns `true` if the map is empty. - pub fn is_empty(&self, store: &dyn Storage) -> bool { - self.no_prefix_raw() - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .next() - .is_none() - } -} - #[cfg(test)] mod test { use super::*; From 4acfd1211eec09821febfb871e4f573a5f7098b8 Mon Sep 17 00:00:00 2001 From: Manuel Turetta Date: Mon, 26 Sep 2022 23:47:08 +0200 Subject: [PATCH 463/631] Add clear and is_empty to IndexedMap --- packages/storage-plus/src/indexed_map.rs | 53 ++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs index 8fe7f725c..4ea2e4e27 100644 --- a/packages/storage-plus/src/indexed_map.rs +++ b/packages/storage-plus/src/indexed_map.rs @@ -139,6 +139,34 @@ where fn no_prefix_raw(&self) -> Prefix, T, K> { Prefix::new(self.pk_namespace, &[]) } + + /// Clears the map, removing all elements. + pub fn clear(&self, store: &mut dyn Storage) { + const TAKE: usize = 10; + let mut cleared = false; + + while !cleared { + let paths = self + .no_prefix_raw() + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .map(|raw_key| Path::::new(self.pk_namespace, &[raw_key.as_slice()])) + // Take just TAKE elements to prevent possible heap overflow if the Map is big. + .take(TAKE) + .collect::>(); + + paths.iter().for_each(|path| store.remove(path)); + + cleared = paths.len() < TAKE; + } + } + + /// Returns `true` if the map is empty. + pub fn is_empty(&self, store: &dyn Storage) -> bool { + self.no_prefix_raw() + .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) + .next() + .is_none() + } } #[cfg(feature = "iterator")] @@ -1679,4 +1707,29 @@ mod test { ); } } + + #[test] + fn clear_works() { + let mut storage = MockStorage::new(); + let map = build_map(); + let (pks, _) = save_data(&mut storage, &map); + + map.clear(&mut storage); + + for key in pks { + assert!(!map.has(&storage, key)); + } + } + + #[test] + fn is_empty_works() { + let mut storage = MockStorage::new(); + let map = build_map(); + + assert!(map.is_empty(&storage)); + + save_data(&mut storage, &map); + + assert!(!map.is_empty(&storage)); + } } From bd08192b31f12753d1f669fc689ef8d4e141604d Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Mon, 26 Sep 2022 21:56:34 -0500 Subject: [PATCH 464/631] Moved execute and query logic to modules https://github.com/CosmWasm/cw-plus/pull/804#discussion_r979888833 --- contracts/cw1155-base/src/contract.rs | 494 +------------------------- contracts/cw1155-base/src/execute.rs | 312 ++++++++++++++++ contracts/cw1155-base/src/helpers.rs | 30 ++ contracts/cw1155-base/src/lib.rs | 3 + contracts/cw1155-base/src/query.rs | 130 +++++++ 5 files changed, 493 insertions(+), 476 deletions(-) create mode 100644 contracts/cw1155-base/src/execute.rs create mode 100644 contracts/cw1155-base/src/helpers.rs create mode 100644 contracts/cw1155-base/src/query.rs diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs index 425609119..eab6b12e8 100644 --- a/contracts/cw1155-base/src/contract.rs +++ b/contracts/cw1155-base/src/contract.rs @@ -1,28 +1,14 @@ -use crate::{ - error::ContractError, - msg::InstantiateMsg, - state::{APPROVES, BALANCES, MINTER, TOKENS}, -}; +use crate::{error::ContractError, execute, msg::InstantiateMsg, query, state::MINTER}; use cosmwasm_std::{ - entry_point, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, - StdResult, SubMsg, Uint128, -}; -use cw1155::{ - ApproveAllEvent, ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, - Cw1155BatchReceiveMsg, Cw1155ExecuteMsg, Cw1155QueryMsg, Cw1155ReceiveMsg, Expiration, - IsApprovedForAllResponse, TokenId, TokenInfoResponse, TokensResponse, TransferEvent, + entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, }; +use cw1155::{Cw1155ExecuteMsg, Cw1155QueryMsg}; use cw2::set_contract_version; -use cw_storage_plus::Bound; -use cw_utils::{maybe_addr, Event}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw1155-base"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -const DEFAULT_LIMIT: u32 = 10; -const MAX_LIMIT: u32 = 30; - #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, @@ -58,380 +44,51 @@ pub fn execute( token_id, value, msg, - } => execute_send_from(env, from, to, token_id, value, msg), + } => execute::send_from(env, from, to, token_id, value, msg), Cw1155ExecuteMsg::BatchSendFrom { from, to, batch, msg, - } => execute_batch_send_from(env, from, to, batch, msg), + } => execute::batch_send_from(env, from, to, batch, msg), Cw1155ExecuteMsg::Mint { to, token_id, value, msg, - } => execute_mint(env, to, token_id, value, msg), - Cw1155ExecuteMsg::BatchMint { to, batch, msg } => execute_batch_mint(env, to, batch, msg), + } => execute::mint(env, to, token_id, value, msg), + Cw1155ExecuteMsg::BatchMint { to, batch, msg } => execute::batch_mint(env, to, batch, msg), Cw1155ExecuteMsg::Burn { from, token_id, value, - } => execute_burn(env, from, token_id, value), - Cw1155ExecuteMsg::BatchBurn { from, batch } => execute_batch_burn(env, from, batch), + } => execute::burn(env, from, token_id, value), + Cw1155ExecuteMsg::BatchBurn { from, batch } => execute::batch_burn(env, from, batch), Cw1155ExecuteMsg::ApproveAll { operator, expires } => { - execute_approve_all(env, operator, expires) - } - Cw1155ExecuteMsg::RevokeAll { operator } => execute_revoke_all(env, operator), - } -} - -/// When from is None: mint new coins -/// When to is None: burn coins -/// When both are None: no token balance is changed, pointless but valid -/// -/// Make sure permissions are checked before calling this. -fn execute_transfer_inner<'a>( - deps: &'a mut DepsMut, - from: Option<&'a Addr>, - to: Option<&'a Addr>, - token_id: &'a str, - amount: Uint128, -) -> Result, ContractError> { - if let Some(from_addr) = from { - BALANCES.update( - deps.storage, - (from_addr, token_id), - |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_sub(amount)?) - }, - )?; - } - - if let Some(to_addr) = to { - BALANCES.update( - deps.storage, - (to_addr, token_id), - |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_add(amount)?) - }, - )?; - } - - Ok(TransferEvent { - from: from.map(|x| x.as_ref()), - to: to.map(|x| x.as_ref()), - token_id, - amount, - }) -} - -/// returns true iff the sender can execute approve or reject on the contract -fn check_can_approve(deps: Deps, env: &Env, owner: &Addr, operator: &Addr) -> StdResult { - // owner can approve - if owner == operator { - return Ok(true); - } - // operator can approve - let op = APPROVES.may_load(deps.storage, (owner, operator))?; - Ok(match op { - Some(ex) => !ex.is_expired(&env.block), - None => false, - }) -} - -fn guard_can_approve( - deps: Deps, - env: &Env, - owner: &Addr, - operator: &Addr, -) -> Result<(), ContractError> { - if !check_can_approve(deps, env, owner, operator)? { - Err(ContractError::Unauthorized {}) - } else { - Ok(()) - } -} - -pub fn execute_send_from( - env: ExecuteEnv, - from: String, - to: String, - token_id: TokenId, - amount: Uint128, - msg: Option, -) -> Result { - let from_addr = env.deps.api.addr_validate(&from)?; - let to_addr = env.deps.api.addr_validate(&to)?; - - let ExecuteEnv { - mut deps, - env, - info, - } = env; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - - let event = execute_transfer_inner( - &mut deps, - Some(&from_addr), - Some(&to_addr), - &token_id, - amount, - )?; - event.add_attributes(&mut rsp); - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155ReceiveMsg { - operator: info.sender.to_string(), - from: Some(from), - amount, - token_id: token_id.clone(), - msg, - } - .into_cosmos_msg(to)?, - )] - } - - Ok(rsp) -} - -pub fn execute_mint( - env: ExecuteEnv, - to: String, - token_id: TokenId, - amount: Uint128, - msg: Option, -) -> Result { - let ExecuteEnv { mut deps, info, .. } = env; - - let to_addr = deps.api.addr_validate(&to)?; - - if info.sender != MINTER.load(deps.storage)? { - return Err(ContractError::Unauthorized {}); - } - - let mut rsp = Response::default(); - - let event = execute_transfer_inner(&mut deps, None, Some(&to_addr), &token_id, amount)?; - event.add_attributes(&mut rsp); - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155ReceiveMsg { - operator: info.sender.to_string(), - from: None, - amount, - token_id: token_id.clone(), - msg, - } - .into_cosmos_msg(to)?, - )] - } - - // insert if not exist - if !TOKENS.has(deps.storage, &token_id) { - // we must save some valid data here - TOKENS.save(deps.storage, &token_id, &String::new())?; - } - - Ok(rsp) -} - -pub fn execute_burn( - env: ExecuteEnv, - from: String, - token_id: TokenId, - amount: Uint128, -) -> Result { - let ExecuteEnv { - mut deps, - info, - env, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - - // whoever can transfer these tokens can burn - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - let event = execute_transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; - event.add_attributes(&mut rsp); - Ok(rsp) -} - -pub fn execute_batch_send_from( - env: ExecuteEnv, - from: String, - to: String, - batch: Vec<(TokenId, Uint128)>, - msg: Option, -) -> Result { - let ExecuteEnv { - mut deps, - env, - info, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - let to_addr = deps.api.addr_validate(&to)?; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - for (token_id, amount) in batch.iter() { - let event = execute_transfer_inner( - &mut deps, - Some(&from_addr), - Some(&to_addr), - token_id, - *amount, - )?; - event.add_attributes(&mut rsp); - } - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155BatchReceiveMsg { - operator: info.sender.to_string(), - from: Some(from), - batch, - msg, - } - .into_cosmos_msg(to)?, - )] - }; - - Ok(rsp) -} - -pub fn execute_batch_mint( - env: ExecuteEnv, - to: String, - batch: Vec<(TokenId, Uint128)>, - msg: Option, -) -> Result { - let ExecuteEnv { mut deps, info, .. } = env; - if info.sender != MINTER.load(deps.storage)? { - return Err(ContractError::Unauthorized {}); - } - - let to_addr = deps.api.addr_validate(&to)?; - - let mut rsp = Response::default(); - - for (token_id, amount) in batch.iter() { - let event = execute_transfer_inner(&mut deps, None, Some(&to_addr), token_id, *amount)?; - event.add_attributes(&mut rsp); - - // insert if not exist - if !TOKENS.has(deps.storage, token_id) { - // we must save some valid data here - TOKENS.save(deps.storage, token_id, &String::new())?; + execute::approve_all(env, operator, expires) } + Cw1155ExecuteMsg::RevokeAll { operator } => execute::revoke_all(env, operator), } - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155BatchReceiveMsg { - operator: info.sender.to_string(), - from: None, - batch, - msg, - } - .into_cosmos_msg(to)?, - )] - }; - - Ok(rsp) -} - -pub fn execute_batch_burn( - env: ExecuteEnv, - from: String, - batch: Vec<(TokenId, Uint128)>, -) -> Result { - let ExecuteEnv { - mut deps, - info, - env, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - for (token_id, amount) in batch.into_iter() { - let event = execute_transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; - event.add_attributes(&mut rsp); - } - Ok(rsp) -} - -pub fn execute_approve_all( - env: ExecuteEnv, - operator: String, - expires: Option, -) -> Result { - let ExecuteEnv { deps, info, env } = env; - - // reject expired data as invalid - let expires = expires.unwrap_or_default(); - if expires.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - - // set the operator for us - let operator_addr = deps.api.addr_validate(&operator)?; - APPROVES.save(deps.storage, (&info.sender, &operator_addr), &expires)?; - - let mut rsp = Response::default(); - ApproveAllEvent { - sender: info.sender.as_ref(), - operator: &operator, - approved: true, - } - .add_attributes(&mut rsp); - Ok(rsp) -} - -pub fn execute_revoke_all(env: ExecuteEnv, operator: String) -> Result { - let ExecuteEnv { deps, info, .. } = env; - let operator_addr = deps.api.addr_validate(&operator)?; - APPROVES.remove(deps.storage, (&info.sender, &operator_addr)); - - let mut rsp = Response::default(); - ApproveAllEvent { - sender: info.sender.as_ref(), - operator: &operator, - approved: false, - } - .add_attributes(&mut rsp); - Ok(rsp) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: Cw1155QueryMsg) -> StdResult { match msg { Cw1155QueryMsg::Balance { owner, token_id } => { - to_binary(&query_balance(deps, owner, token_id)?) + to_binary(&query::balance(deps, owner, token_id)?) } Cw1155QueryMsg::BatchBalance { owner, token_ids } => { - to_binary(&query_batch_balance(deps, owner, token_ids)?) + to_binary(&query::batch_balance(deps, owner, token_ids)?) } Cw1155QueryMsg::IsApprovedForAll { owner, operator } => { - to_binary(&query_is_approved_for_all(deps, env, owner, operator)?) + to_binary(&query::is_approved_for_all(deps, env, owner, operator)?) } Cw1155QueryMsg::ApprovedForAll { owner, include_expired, start_after, limit, - } => to_binary(&query_approved_for_all( + } => to_binary(&query::approved_for_all( deps, env, owner, @@ -439,129 +96,14 @@ pub fn query(deps: Deps, env: Env, msg: Cw1155QueryMsg) -> StdResult { start_after, limit, )?), - Cw1155QueryMsg::TokenInfo { token_id } => to_binary(&query_token_info(deps, token_id)?), + Cw1155QueryMsg::TokenInfo { token_id } => to_binary(&query::token_info(deps, token_id)?), Cw1155QueryMsg::Tokens { owner, start_after, limit, - } => to_binary(&query_tokens(deps, owner, start_after, limit)?), + } => to_binary(&query::tokens(deps, owner, start_after, limit)?), Cw1155QueryMsg::AllTokens { start_after, limit } => { - to_binary(&query_all_tokens(deps, start_after, limit)?) + to_binary(&query::all_tokens(deps, start_after, limit)?) } } } - -pub fn query_balance(deps: Deps, owner: String, token_id: String) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - - let balance = BALANCES - .may_load(deps.storage, (&owner, &token_id))? - .unwrap_or_default(); - - Ok(BalanceResponse { balance }) -} - -pub fn query_batch_balance( - deps: Deps, - owner: String, - token_ids: Vec, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - - let balances = token_ids - .into_iter() - .map(|token_id| -> StdResult<_> { - Ok(BALANCES - .may_load(deps.storage, (&owner, &token_id))? - .unwrap_or_default()) - }) - .collect::>()?; - - Ok(BatchBalanceResponse { balances }) -} - -fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult { - item.map(|(addr, expires)| cw1155::Approval { - spender: addr.into(), - expires, - }) -} - -pub fn query_approved_for_all( - deps: Deps, - env: Env, - owner: String, - include_expired: bool, - start_after: Option, - limit: Option, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - let start_after = maybe_addr(deps.api, start_after)?; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.as_ref().map(Bound::exclusive); - - let operators = APPROVES - .prefix(&owner) - .range(deps.storage, start, None, Order::Ascending) - .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) - .take(limit) - .map(build_approval) - .collect::>()?; - - Ok(ApprovedForAllResponse { operators }) -} - -pub fn query_token_info(deps: Deps, token_id: String) -> StdResult { - let url = TOKENS.load(deps.storage, &token_id)?; - - Ok(TokenInfoResponse { url }) -} - -pub fn query_is_approved_for_all( - deps: Deps, - env: Env, - owner: String, - operator: String, -) -> StdResult { - let owner_addr = deps.api.addr_validate(&owner)?; - let operator_addr = deps.api.addr_validate(&operator)?; - - let approved = check_can_approve(deps, &env, &owner_addr, &operator_addr)?; - - Ok(IsApprovedForAllResponse { approved }) -} - -pub fn query_tokens( - deps: Deps, - owner: String, - start_after: Option, - limit: Option, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); - - let tokens = BALANCES - .prefix(&owner) - .keys(deps.storage, start, None, Order::Ascending) - .take(limit) - .collect::>()?; - - Ok(TokensResponse { tokens }) -} - -pub fn query_all_tokens( - deps: Deps, - start_after: Option, - limit: Option, -) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - 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) - .collect::>()?; - - Ok(TokensResponse { tokens }) -} diff --git a/contracts/cw1155-base/src/execute.rs b/contracts/cw1155-base/src/execute.rs new file mode 100644 index 000000000..ab5a56d78 --- /dev/null +++ b/contracts/cw1155-base/src/execute.rs @@ -0,0 +1,312 @@ +use cosmwasm_std::{Addr, Binary, DepsMut, Response, StdResult, SubMsg, Uint128}; +use cw1155::{ApproveAllEvent, Cw1155BatchReceiveMsg, Cw1155ReceiveMsg, TokenId, TransferEvent}; +use cw_utils::{Event, Expiration}; + +use crate::{ + contract::ExecuteEnv, + helpers::guard_can_approve, + state::{APPROVES, BALANCES, MINTER, TOKENS}, + ContractError, +}; + +/// When from is None: mint new coins +/// When to is None: burn coins +/// When both are None: no token balance is changed, pointless but valid +/// +/// Make sure permissions are checked before calling this. +fn transfer_inner<'a>( + deps: &'a mut DepsMut, + from: Option<&'a Addr>, + to: Option<&'a Addr>, + token_id: &'a str, + amount: Uint128, +) -> Result, ContractError> { + if let Some(from_addr) = from { + BALANCES.update( + deps.storage, + (from_addr, token_id), + |balance: Option| -> StdResult<_> { + Ok(balance.unwrap_or_default().checked_sub(amount)?) + }, + )?; + } + + if let Some(to_addr) = to { + BALANCES.update( + deps.storage, + (to_addr, token_id), + |balance: Option| -> StdResult<_> { + Ok(balance.unwrap_or_default().checked_add(amount)?) + }, + )?; + } + + Ok(TransferEvent { + from: from.map(|x| x.as_ref()), + to: to.map(|x| x.as_ref()), + token_id, + amount, + }) +} + +pub fn send_from( + env: ExecuteEnv, + from: String, + to: String, + token_id: TokenId, + amount: Uint128, + msg: Option, +) -> Result { + let from_addr = env.deps.api.addr_validate(&from)?; + let to_addr = env.deps.api.addr_validate(&to)?; + + let ExecuteEnv { + mut deps, + env, + info, + } = env; + + guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; + + let mut rsp = Response::default(); + + let event = transfer_inner( + &mut deps, + Some(&from_addr), + Some(&to_addr), + &token_id, + amount, + )?; + event.add_attributes(&mut rsp); + + if let Some(msg) = msg { + rsp.messages = vec![SubMsg::new( + Cw1155ReceiveMsg { + operator: info.sender.to_string(), + from: Some(from), + amount, + token_id: token_id.clone(), + msg, + } + .into_cosmos_msg(to)?, + )] + } + + Ok(rsp) +} + +pub fn mint( + env: ExecuteEnv, + to: String, + token_id: TokenId, + amount: Uint128, + msg: Option, +) -> Result { + let ExecuteEnv { mut deps, info, .. } = env; + + let to_addr = deps.api.addr_validate(&to)?; + + if info.sender != MINTER.load(deps.storage)? { + return Err(ContractError::Unauthorized {}); + } + + let mut rsp = Response::default(); + + let event = transfer_inner(&mut deps, None, Some(&to_addr), &token_id, amount)?; + event.add_attributes(&mut rsp); + + if let Some(msg) = msg { + rsp.messages = vec![SubMsg::new( + Cw1155ReceiveMsg { + operator: info.sender.to_string(), + from: None, + amount, + token_id: token_id.clone(), + msg, + } + .into_cosmos_msg(to)?, + )] + } + + // insert if not exist + if !TOKENS.has(deps.storage, &token_id) { + // we must save some valid data here + TOKENS.save(deps.storage, &token_id, &String::new())?; + } + + Ok(rsp) +} + +pub fn burn( + env: ExecuteEnv, + from: String, + token_id: TokenId, + amount: Uint128, +) -> Result { + let ExecuteEnv { + mut deps, + info, + env, + } = env; + + let from_addr = deps.api.addr_validate(&from)?; + + // whoever can transfer these tokens can burn + guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; + + let mut rsp = Response::default(); + let event = transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; + event.add_attributes(&mut rsp); + Ok(rsp) +} + +pub fn batch_send_from( + env: ExecuteEnv, + from: String, + to: String, + batch: Vec<(TokenId, Uint128)>, + msg: Option, +) -> Result { + let ExecuteEnv { + mut deps, + env, + info, + } = env; + + let from_addr = deps.api.addr_validate(&from)?; + let to_addr = deps.api.addr_validate(&to)?; + + guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; + + let mut rsp = Response::default(); + for (token_id, amount) in batch.iter() { + let event = transfer_inner( + &mut deps, + Some(&from_addr), + Some(&to_addr), + token_id, + *amount, + )?; + event.add_attributes(&mut rsp); + } + + if let Some(msg) = msg { + rsp.messages = vec![SubMsg::new( + Cw1155BatchReceiveMsg { + operator: info.sender.to_string(), + from: Some(from), + batch, + msg, + } + .into_cosmos_msg(to)?, + )] + }; + + Ok(rsp) +} + +pub fn batch_mint( + env: ExecuteEnv, + to: String, + batch: Vec<(TokenId, Uint128)>, + msg: Option, +) -> Result { + let ExecuteEnv { mut deps, info, .. } = env; + if info.sender != MINTER.load(deps.storage)? { + return Err(ContractError::Unauthorized {}); + } + + let to_addr = deps.api.addr_validate(&to)?; + + let mut rsp = Response::default(); + + for (token_id, amount) in batch.iter() { + let event = transfer_inner(&mut deps, None, Some(&to_addr), token_id, *amount)?; + event.add_attributes(&mut rsp); + + // insert if not exist + if !TOKENS.has(deps.storage, token_id) { + // we must save some valid data here + TOKENS.save(deps.storage, token_id, &String::new())?; + } + } + + if let Some(msg) = msg { + rsp.messages = vec![SubMsg::new( + Cw1155BatchReceiveMsg { + operator: info.sender.to_string(), + from: None, + batch, + msg, + } + .into_cosmos_msg(to)?, + )] + }; + + Ok(rsp) +} + +pub fn batch_burn( + env: ExecuteEnv, + from: String, + batch: Vec<(TokenId, Uint128)>, +) -> Result { + let ExecuteEnv { + mut deps, + info, + env, + } = env; + + let from_addr = deps.api.addr_validate(&from)?; + + guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; + + let mut rsp = Response::default(); + for (token_id, amount) in batch.into_iter() { + let event = transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; + event.add_attributes(&mut rsp); + } + Ok(rsp) +} + +pub fn approve_all( + env: ExecuteEnv, + operator: String, + expires: Option, +) -> Result { + let ExecuteEnv { deps, info, env } = env; + + // reject expired data as invalid + let expires = expires.unwrap_or_default(); + if expires.is_expired(&env.block) { + return Err(ContractError::Expired {}); + } + + // set the operator for us + let operator_addr = deps.api.addr_validate(&operator)?; + APPROVES.save(deps.storage, (&info.sender, &operator_addr), &expires)?; + + let mut rsp = Response::default(); + ApproveAllEvent { + sender: info.sender.as_ref(), + operator: &operator, + approved: true, + } + .add_attributes(&mut rsp); + Ok(rsp) +} + +pub fn revoke_all(env: ExecuteEnv, operator: String) -> Result { + let ExecuteEnv { deps, info, .. } = env; + let operator_addr = deps.api.addr_validate(&operator)?; + APPROVES.remove(deps.storage, (&info.sender, &operator_addr)); + + let mut rsp = Response::default(); + ApproveAllEvent { + sender: info.sender.as_ref(), + operator: &operator, + approved: false, + } + .add_attributes(&mut rsp); + Ok(rsp) +} diff --git a/contracts/cw1155-base/src/helpers.rs b/contracts/cw1155-base/src/helpers.rs new file mode 100644 index 000000000..638054f3e --- /dev/null +++ b/contracts/cw1155-base/src/helpers.rs @@ -0,0 +1,30 @@ +use cosmwasm_std::{Addr, Deps, Env, StdResult}; + +use crate::{state::APPROVES, ContractError}; + +/// returns true if the sender can execute approve or reject on the contract +pub fn check_can_approve(deps: Deps, env: &Env, owner: &Addr, operator: &Addr) -> StdResult { + // owner can approve + if owner == operator { + return Ok(true); + } + // operator can approve + let op = APPROVES.may_load(deps.storage, (owner, operator))?; + Ok(match op { + Some(ex) => !ex.is_expired(&env.block), + None => false, + }) +} + +pub fn guard_can_approve( + deps: Deps, + env: &Env, + owner: &Addr, + operator: &Addr, +) -> Result<(), ContractError> { + if !check_can_approve(deps, env, owner, operator)? { + Err(ContractError::Unauthorized {}) + } else { + Ok(()) + } +} diff --git a/contracts/cw1155-base/src/lib.rs b/contracts/cw1155-base/src/lib.rs index 69b809fe1..0aa98a4f1 100644 --- a/contracts/cw1155-base/src/lib.rs +++ b/contracts/cw1155-base/src/lib.rs @@ -1,6 +1,9 @@ pub mod contract; mod error; +pub mod execute; +pub mod helpers; pub mod msg; +pub mod query; pub mod state; pub use crate::error::ContractError; diff --git a/contracts/cw1155-base/src/query.rs b/contracts/cw1155-base/src/query.rs new file mode 100644 index 000000000..0b89b0cba --- /dev/null +++ b/contracts/cw1155-base/src/query.rs @@ -0,0 +1,130 @@ +use cosmwasm_std::{Addr, Deps, Env, Order, StdResult}; +use cw1155::{ + ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, IsApprovedForAllResponse, + TokenInfoResponse, TokensResponse, +}; +use cw_storage_plus::Bound; +use cw_utils::{maybe_addr, Expiration}; + +use crate::{ + helpers::check_can_approve, + state::{APPROVES, BALANCES, TOKENS}, +}; + +pub const DEFAULT_LIMIT: u32 = 10; +pub const MAX_LIMIT: u32 = 30; + +pub fn balance(deps: Deps, owner: String, token_id: String) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + + let balance = BALANCES + .may_load(deps.storage, (&owner, &token_id))? + .unwrap_or_default(); + + Ok(BalanceResponse { balance }) +} + +pub fn batch_balance( + deps: Deps, + owner: String, + token_ids: Vec, +) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + + let balances = token_ids + .into_iter() + .map(|token_id| -> StdResult<_> { + Ok(BALANCES + .may_load(deps.storage, (&owner, &token_id))? + .unwrap_or_default()) + }) + .collect::>()?; + + Ok(BatchBalanceResponse { balances }) +} + +fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult { + item.map(|(addr, expires)| cw1155::Approval { + spender: addr.into(), + expires, + }) +} + +pub fn approved_for_all( + deps: Deps, + env: Env, + owner: String, + include_expired: bool, + start_after: Option, + limit: Option, +) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + let start_after = maybe_addr(deps.api, start_after)?; + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.as_ref().map(Bound::exclusive); + + let operators = APPROVES + .prefix(&owner) + .range(deps.storage, start, None, Order::Ascending) + .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) + .take(limit) + .map(build_approval) + .collect::>()?; + + Ok(ApprovedForAllResponse { operators }) +} + +pub fn token_info(deps: Deps, token_id: String) -> StdResult { + let url = TOKENS.load(deps.storage, &token_id)?; + + Ok(TokenInfoResponse { url }) +} + +pub fn is_approved_for_all( + deps: Deps, + env: Env, + owner: String, + operator: String, +) -> StdResult { + let owner_addr = deps.api.addr_validate(&owner)?; + let operator_addr = deps.api.addr_validate(&operator)?; + + let approved = check_can_approve(deps, &env, &owner_addr, &operator_addr)?; + + Ok(IsApprovedForAllResponse { approved }) +} + +pub fn tokens( + deps: Deps, + owner: String, + start_after: Option, + limit: Option, +) -> StdResult { + let owner = deps.api.addr_validate(&owner)?; + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); + + let tokens = BALANCES + .prefix(&owner) + .keys(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect::>()?; + + Ok(TokensResponse { tokens }) +} + +pub fn all_tokens( + deps: Deps, + start_after: Option, + limit: Option, +) -> StdResult { + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + 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) + .collect::>()?; + + Ok(TokensResponse { tokens }) +} From fafa185b3dc2471b9d9ef0e9ff576b0a35c57bf5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 23 Sep 2022 16:51:24 +0200 Subject: [PATCH 465/631] Implement basic queue --- packages/storage-plus/src/lib.rs | 4 + packages/storage-plus/src/queue.rs | 306 +++++++++++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 packages/storage-plus/src/queue.rs diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 03b2b52d1..67b2e9e0b 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -12,6 +12,7 @@ mod keys; mod map; mod path; mod prefix; +mod queue; mod snapshot; #[cfg(feature = "iterator")] @@ -35,6 +36,9 @@ pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] pub use prefix::{range_with_prefix, Prefix}; +pub use queue::Queue; +#[cfg(feature = "iterator")] +pub use queue::QueueIter; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; diff --git a/packages/storage-plus/src/queue.rs b/packages/storage-plus/src/queue.rs new file mode 100644 index 000000000..d55c0695a --- /dev/null +++ b/packages/storage-plus/src/queue.rs @@ -0,0 +1,306 @@ +use std::{convert::TryInto, marker::PhantomData}; + +use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; +use serde::{de::DeserializeOwned, Serialize}; + +use crate::helpers::{may_deserialize, namespaces_with_key}; + +// metadata keys need to have different length than the position type (4 bytes) to prevent collisions +const TAIL_KEY: &[u8] = b"t"; +const HEAD_KEY: &[u8] = b"h"; + +/// A queue stores multiple items at the given key. It provides efficient FIFO access. +pub struct Queue<'a, T> { + // prefix of the queue items + namespace: &'a [u8], + // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed + item_type: PhantomData, +} + +impl<'a, T> Queue<'a, T> { + pub const fn new(prefix: &'a str) -> Self { + Self { + namespace: prefix.as_bytes(), + item_type: PhantomData, + } + } +} + +impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { + /// Adds the given value to the end of the queue + pub fn push(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { + // save value + let pos = self.tail(storage)?; + self.set_at(storage, pos, value)?; + // update tail + self.set_tail(storage, pos.wrapping_add(1)); + + Ok(()) + } + + /// Removes the first item of the queue and returns it + pub fn pop(&self, storage: &mut dyn Storage) -> StdResult> { + // get position + let pos = self.head(storage)?; + let value = self.get_at(storage, pos)?; + if value.is_some() { + self.remove_at(storage, pos); + // only update head if a value was popped + self.set_head(storage, pos.wrapping_add(1)); + } + Ok(value) + } + + /// Gets the length of the queue. + pub fn len(&self, storage: &dyn Storage) -> StdResult { + Ok(self.tail(storage)?.wrapping_sub(self.head(storage)?)) + } + + /// Returns `true` if the queue contains no elements. + pub fn is_empty(&self, storage: &dyn Storage) -> StdResult { + Ok(self.len(storage)? == 0) + } + + /// Gets the head position from storage. + /// + /// Points to the front of the queue (where elements are popped). + fn head(&self, storage: &dyn Storage) -> StdResult { + self.read_meta_key(storage, HEAD_KEY) + } + + /// Gets the tail position from storage. + /// + /// Points to the end of the queue (where elements are pushed). + fn tail(&self, storage: &dyn Storage) -> StdResult { + self.read_meta_key(storage, TAIL_KEY) + } + + fn set_head(&self, storage: &mut dyn Storage, value: u32) { + self.set_meta_key(storage, HEAD_KEY, value); + } + + fn set_tail(&self, storage: &mut dyn Storage, value: u32) { + self.set_meta_key(storage, TAIL_KEY, value); + } + + /// Helper method for `tail` and `head` methods to handle reading the value from storage + fn read_meta_key(&self, storage: &dyn Storage, key: &[u8]) -> StdResult { + let full_key = namespaces_with_key(&[self.namespace], key); + storage + .get(&full_key) + .map(|vec| { + Ok(u32::from_be_bytes( + vec.as_slice() + .try_into() + .map_err(|e| StdError::parse_err("u32", e))?, + )) + }) + .unwrap_or(Ok(0)) + } + + /// Helper method for `set_tail` and `set_head` methods to write to storage + #[inline] + fn set_meta_key(&self, storage: &mut dyn Storage, key: &[u8], value: u32) { + let full_key = namespaces_with_key(&[self.namespace], key); + storage.set(&full_key, &value.to_be_bytes()); + } + + /// Tries to get the value at the given position (without bounds checking) + /// Used internally when popping + fn get_at(&self, storage: &dyn Storage, pos: u32) -> StdResult> { + let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); + may_deserialize(&storage.get(&prefixed_key)) + } + + /// Removes the value at the given position + /// Used internally when popping + fn remove_at(&self, storage: &mut dyn Storage, pos: u32) { + let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); + storage.remove(&prefixed_key); + } + + /// Tries to set the value at the given position (without bounds checking) + /// Used internally when pushing + fn set_at(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { + let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); + storage.set(&prefixed_key, &to_vec(value)?); + + Ok(()) + } +} + +#[cfg(feature = "iterator")] +impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { + pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { + Ok(QueueIter { + queue: self, + storage, + start: self.head(storage)?, + end: self.tail(storage)?, + }) + } +} + +#[cfg(feature = "iterator")] +pub struct QueueIter<'a, T> +where + T: Serialize + DeserializeOwned, +{ + queue: &'a Queue<'a, T>, + storage: &'a dyn Storage, + start: u32, + end: u32, +} + +impl<'a, T> Iterator for QueueIter<'a, T> +where + T: Serialize + DeserializeOwned, +{ + type Item = StdResult; + + fn next(&mut self) -> Option { + if self.start == self.end { + return None; + } + + let item = self.queue.get_at(self.storage, self.start).transpose()?; + self.start = self.start.wrapping_add(1); + + Some(item) + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.end.wrapping_sub(self.start) as usize; + (len, Some(len)) + } + + /// The default implementation calls `next` repeatedly, which is very costly in our case. + /// It is used when skipping over items, so this allows cheap skipping. + /// + /// Once `advance_by` is stabilized, we can implement that instead (`nth` calls it internally). + fn nth(&mut self, n: usize) -> Option { + let start_lt_end = self.start < self.end; + self.start = self.start.wrapping_add(n as u32); + // make sure that we didn't skip past the end + if self.start > self.end && start_lt_end || self.start < self.end && !start_lt_end { + // start and end switched places, which means the iterator is empty now + self.start = self.end; + } + self.next() + } +} + +#[cfg(test)] +mod tests { + use crate::queue::Queue; + + use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::StdResult; + + #[test] + fn push_and_pop() { + const PEOPLE: Queue = Queue::new("people"); + let mut store = MockStorage::new(); + + // push some entries + PEOPLE.push(&mut store, &"jack".to_owned()).unwrap(); + PEOPLE.push(&mut store, &"john".to_owned()).unwrap(); + PEOPLE.push(&mut store, &"joanne".to_owned()).unwrap(); + + // pop them, should be in correct order + assert_eq!("jack", PEOPLE.pop(&mut store).unwrap().unwrap()); + assert_eq!("john", PEOPLE.pop(&mut store).unwrap().unwrap()); + + // push again in-between + PEOPLE.push(&mut store, &"jason".to_owned()).unwrap(); + + // pop last person from first batch + assert_eq!("joanne", PEOPLE.pop(&mut store).unwrap().unwrap()); + + // pop the entry pushed in-between + assert_eq!("jason", PEOPLE.pop(&mut store).unwrap().unwrap()); + + // nothing after that + assert_eq!(None, PEOPLE.pop(&mut store).unwrap()); + } + + #[test] + fn length() { + let queue: Queue = Queue::new("test"); + let mut store = MockStorage::new(); + + assert_eq!(queue.len(&store).unwrap(), 0); + + // push some entries + queue.push(&mut store, &1234).unwrap(); + queue.push(&mut store, &2345).unwrap(); + queue.push(&mut store, &3456).unwrap(); + queue.push(&mut store, &4567).unwrap(); + assert_eq!(queue.len(&store).unwrap(), 4); + + // pop some + queue.pop(&mut store).unwrap(); + queue.pop(&mut store).unwrap(); + queue.pop(&mut store).unwrap(); + assert_eq!(queue.len(&store).unwrap(), 1); + + // pop the last one + queue.pop(&mut store).unwrap(); + assert_eq!(queue.len(&store).unwrap(), 0); + + // should stay 0 after that + queue.pop(&mut store).unwrap(); + assert_eq!( + queue.len(&store).unwrap(), + 0, + "popping from empty queue should keep length 0" + ); + } + + #[test] + fn iterator() { + let queue: Queue = Queue::new("test"); + let mut store = MockStorage::new(); + + // push some items + queue.push(&mut store, &1).unwrap(); + queue.push(&mut store, &2).unwrap(); + queue.push(&mut store, &3).unwrap(); + queue.push(&mut store, &4).unwrap(); + + let items: StdResult> = queue.iter(&mut store).unwrap().collect(); + assert_eq!(items.unwrap(), [1, 2, 3, 4]); + + let mut iter = queue.iter(&mut store).unwrap(); + assert_eq!(iter.nth(6), None); + assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); + assert_eq!(iter.next(), None); + } + + #[test] + fn wrapping() { + let queue: Queue = Queue::new("test"); + let mut store = MockStorage::new(); + + // simulate queue that was pushed and popped `u32::MAX` times + queue.set_head(&mut store, u32::MAX); + queue.set_tail(&mut store, u32::MAX); + + // should be empty + assert_eq!(queue.pop(&mut store).unwrap(), None); + assert_eq!(queue.len(&store).unwrap(), 0); + + // pushing should still work + queue.push(&mut store, &1).unwrap(); + assert_eq!( + queue.len(&store).unwrap(), + 1, + "length should calculate correctly, even when wrapping" + ); + assert_eq!( + queue.pop(&mut store).unwrap(), + Some(1), + "popping should work, even when wrapping" + ); + } +} From b43413844dfca80ef4c7c7e6a5b1c1da8ad28af1 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 11:50:36 +0200 Subject: [PATCH 466/631] Add double ended iterator for queue --- packages/storage-plus/src/queue.rs | 48 ++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/storage-plus/src/queue.rs b/packages/storage-plus/src/queue.rs index d55c0695a..5cf3dd14a 100644 --- a/packages/storage-plus/src/queue.rs +++ b/packages/storage-plus/src/queue.rs @@ -174,22 +174,52 @@ where (len, Some(len)) } - /// The default implementation calls `next` repeatedly, which is very costly in our case. - /// It is used when skipping over items, so this allows cheap skipping. - /// - /// Once `advance_by` is stabilized, we can implement that instead (`nth` calls it internally). + // The default implementation calls `next` repeatedly, which is very costly in our case. + // It is used when skipping over items, so this allows cheap skipping. + // + // Once `advance_by` is stabilized, we can implement that instead (`nth` calls it internally). fn nth(&mut self, n: usize) -> Option { - let start_lt_end = self.start < self.end; - self.start = self.start.wrapping_add(n as u32); - // make sure that we didn't skip past the end - if self.start > self.end && start_lt_end || self.start < self.end && !start_lt_end { - // start and end switched places, which means the iterator is empty now + // make sure that we don't skip past the end + if self.end.wrapping_sub(self.start) < n as u32 { + // mark as empty self.start = self.end; + } else { + self.start = self.start.wrapping_add(n as u32); } self.next() } } +impl<'a, T> DoubleEndedIterator for QueueIter<'a, T> +where + T: Serialize + DeserializeOwned, +{ + fn next_back(&mut self) -> Option { + if self.start == self.end { + return None; + } + + let item = self + .queue + .get_at(self.storage, self.end.wrapping_sub(1)) // end points to position after last element + .transpose()?; + self.end = self.end.wrapping_sub(1); + + Some(item) + } + + // see [`QueueIter::nth`] + fn nth_back(&mut self, n: usize) -> Option { + // make sure that we don't skip past the start + if self.end.wrapping_sub(self.start) < n as u32 { + // mark as empty + self.end = self.start; + } else { + self.end = self.end.wrapping_sub(n as u32); + } + self.next_back() + } +} #[cfg(test)] mod tests { use crate::queue::Queue; From 8bc0e959983188b48384b32e170d56acf833b9da Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 11:52:00 +0200 Subject: [PATCH 467/631] Add more queue tests --- packages/storage-plus/src/queue.rs | 71 ++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/queue.rs b/packages/storage-plus/src/queue.rs index 5cf3dd14a..92fe5e4b0 100644 --- a/packages/storage-plus/src/queue.rs +++ b/packages/storage-plus/src/queue.rs @@ -38,7 +38,7 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { Ok(()) } - /// Removes the first item of the queue and returns it + /// Removes the first element of the queue and returns it pub fn pop(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.head(storage)?; @@ -63,22 +63,26 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { /// Gets the head position from storage. /// - /// Points to the front of the queue (where elements are popped). + /// Unless the queue is empty, this points to the first element. + #[inline] fn head(&self, storage: &dyn Storage) -> StdResult { self.read_meta_key(storage, HEAD_KEY) } /// Gets the tail position from storage. /// - /// Points to the end of the queue (where elements are pushed). + /// This points to the first empty position after the last element. + #[inline] fn tail(&self, storage: &dyn Storage) -> StdResult { self.read_meta_key(storage, TAIL_KEY) } + #[inline] fn set_head(&self, storage: &mut dyn Storage, value: u32) { self.set_meta_key(storage, HEAD_KEY, value); } + #[inline] fn set_tail(&self, storage: &mut dyn Storage, value: u32) { self.set_meta_key(storage, TAIL_KEY, value); } @@ -260,6 +264,7 @@ mod tests { let mut store = MockStorage::new(); assert_eq!(queue.len(&store).unwrap(), 0); + assert_eq!(queue.is_empty(&store).unwrap(), true); // push some entries queue.push(&mut store, &1234).unwrap(); @@ -267,16 +272,19 @@ mod tests { queue.push(&mut store, &3456).unwrap(); queue.push(&mut store, &4567).unwrap(); assert_eq!(queue.len(&store).unwrap(), 4); + assert_eq!(queue.is_empty(&store).unwrap(), false); // pop some queue.pop(&mut store).unwrap(); queue.pop(&mut store).unwrap(); queue.pop(&mut store).unwrap(); assert_eq!(queue.len(&store).unwrap(), 1); + assert_eq!(queue.is_empty(&store).unwrap(), false); // pop the last one queue.pop(&mut store).unwrap(); assert_eq!(queue.len(&store).unwrap(), 0); + assert_eq!(queue.is_empty(&store).unwrap(), true); // should stay 0 after that queue.pop(&mut store).unwrap(); @@ -285,6 +293,7 @@ mod tests { 0, "popping from empty queue should keep length 0" ); + assert_eq!(queue.is_empty(&store).unwrap(), true); } #[test] @@ -301,10 +310,49 @@ mod tests { let items: StdResult> = queue.iter(&mut store).unwrap().collect(); assert_eq!(items.unwrap(), [1, 2, 3, 4]); + // nth should work correctly let mut iter = queue.iter(&mut store).unwrap(); assert_eq!(iter.nth(6), None); assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); assert_eq!(iter.next(), None); + + let mut iter = queue.iter(&mut store).unwrap(); + assert_eq!(iter.nth(1).unwrap().unwrap(), 2); + assert_eq!(iter.next().unwrap().unwrap(), 3); + } + + #[test] + fn reverse_iterator() { + let queue: Queue = Queue::new("test"); + let mut store = MockStorage::new(); + + // push some items + queue.push(&mut store, &1).unwrap(); + queue.push(&mut store, &2).unwrap(); + queue.push(&mut store, &3).unwrap(); + queue.push(&mut store, &4).unwrap(); + + let items: StdResult> = queue.iter(&mut store).unwrap().rev().collect(); + assert_eq!(items.unwrap(), [4, 3, 2, 1]); + + // nth should work correctly + let mut iter = queue.iter(&mut store).unwrap(); + assert_eq!(iter.nth_back(6), None); + assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); + assert_eq!(iter.next_back(), None); + + let mut iter = queue.iter(&mut store).unwrap().rev(); + assert_eq!(iter.nth(1).unwrap().unwrap(), 3); + assert_eq!(iter.next().unwrap().unwrap(), 2); + + // mixed + let mut iter = queue.iter(&mut store).unwrap(); + assert_eq!(iter.next().unwrap().unwrap(), 1); + assert_eq!(iter.next_back().unwrap().unwrap(), 4); + assert_eq!(iter.next_back().unwrap().unwrap(), 3); + assert_eq!(iter.next().unwrap().unwrap(), 2); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); } #[test] @@ -332,5 +380,22 @@ mod tests { Some(1), "popping should work, even when wrapping" ); + + queue.set_head(&mut store, u32::MAX); + queue.set_tail(&mut store, u32::MAX); + + queue.push(&mut store, &1).unwrap(); + queue.push(&mut store, &2).unwrap(); + queue.push(&mut store, &3).unwrap(); + queue.push(&mut store, &4).unwrap(); + queue.push(&mut store, &5).unwrap(); + + let mut iter = queue.iter(&store).unwrap(); + assert_eq!(iter.next().unwrap().unwrap(), 1); + assert_eq!(iter.next().unwrap().unwrap(), 2); + assert_eq!(iter.next_back().unwrap().unwrap(), 5); + assert_eq!(iter.nth(1).unwrap().unwrap(), 4); + assert_eq!(iter.nth(1), None); + assert_eq!(iter.start, iter.end); } } From f339278a242bc2722ad6270860a05ad7450f8da9 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 12:24:50 +0200 Subject: [PATCH 468/631] Add deque functionality to queue --- .../storage-plus/src/{queue.rs => deque.rs} | 157 +++++++++++------- packages/storage-plus/src/lib.rs | 8 +- 2 files changed, 99 insertions(+), 66 deletions(-) rename packages/storage-plus/src/{queue.rs => deque.rs} (69%) diff --git a/packages/storage-plus/src/queue.rs b/packages/storage-plus/src/deque.rs similarity index 69% rename from packages/storage-plus/src/queue.rs rename to packages/storage-plus/src/deque.rs index 92fe5e4b0..3366fd335 100644 --- a/packages/storage-plus/src/queue.rs +++ b/packages/storage-plus/src/deque.rs @@ -10,14 +10,14 @@ const TAIL_KEY: &[u8] = b"t"; const HEAD_KEY: &[u8] = b"h"; /// A queue stores multiple items at the given key. It provides efficient FIFO access. -pub struct Queue<'a, T> { - // prefix of the queue items +pub struct Deque<'a, T> { + // prefix of the deque items namespace: &'a [u8], // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed item_type: PhantomData, } -impl<'a, T> Queue<'a, T> { +impl<'a, T> Deque<'a, T> { pub const fn new(prefix: &'a str) -> Self { Self { namespace: prefix.as_bytes(), @@ -26,9 +26,9 @@ impl<'a, T> Queue<'a, T> { } } -impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { - /// Adds the given value to the end of the queue - pub fn push(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { +impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { + /// Adds the given value to the end of the deque + pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // save value let pos = self.tail(storage)?; self.set_at(storage, pos, value)?; @@ -38,8 +38,32 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { Ok(()) } - /// Removes the first element of the queue and returns it - pub fn pop(&self, storage: &mut dyn Storage) -> StdResult> { + /// Adds the given value to the front of the deque + pub fn push_front(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { + // need to subtract first, because head potentially points to existing element + let pos = self.head(storage)?.wrapping_sub(1); + self.set_at(storage, pos, value)?; + // update head + self.set_head(storage, pos); + + Ok(()) + } + + /// Removes the last element of the deque and returns it + pub fn pop_back(&self, storage: &mut dyn Storage) -> StdResult> { + // get position + let pos = self.tail(storage)?.wrapping_sub(1); + let value = self.get_at(storage, pos)?; + if value.is_some() { + self.remove_at(storage, pos); + // only update tail if a value was popped + self.set_tail(storage, pos); + } + Ok(value) + } + + /// Removes the first element of the deque and returns it + pub fn pop_front(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.head(storage)?; let value = self.get_at(storage, pos)?; @@ -51,19 +75,19 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { Ok(value) } - /// Gets the length of the queue. + /// Gets the length of the deque. pub fn len(&self, storage: &dyn Storage) -> StdResult { Ok(self.tail(storage)?.wrapping_sub(self.head(storage)?)) } - /// Returns `true` if the queue contains no elements. + /// Returns `true` if the deque contains no elements. pub fn is_empty(&self, storage: &dyn Storage) -> StdResult { Ok(self.len(storage)? == 0) } /// Gets the head position from storage. /// - /// Unless the queue is empty, this points to the first element. + /// Unless the deque is empty, this points to the first element. #[inline] fn head(&self, storage: &dyn Storage) -> StdResult { self.read_meta_key(storage, HEAD_KEY) @@ -134,10 +158,10 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { } #[cfg(feature = "iterator")] -impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { - pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { - Ok(QueueIter { - queue: self, +impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { + pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { + Ok(DequeIter { + deque: self, storage, start: self.head(storage)?, end: self.tail(storage)?, @@ -146,17 +170,17 @@ impl<'a, T: Serialize + DeserializeOwned> Queue<'a, T> { } #[cfg(feature = "iterator")] -pub struct QueueIter<'a, T> +pub struct DequeIter<'a, T> where T: Serialize + DeserializeOwned, { - queue: &'a Queue<'a, T>, + deque: &'a Deque<'a, T>, storage: &'a dyn Storage, start: u32, end: u32, } -impl<'a, T> Iterator for QueueIter<'a, T> +impl<'a, T> Iterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -167,7 +191,7 @@ where return None; } - let item = self.queue.get_at(self.storage, self.start).transpose()?; + let item = self.deque.get_at(self.storage, self.start).transpose()?; self.start = self.start.wrapping_add(1); Some(item) @@ -194,7 +218,7 @@ where } } -impl<'a, T> DoubleEndedIterator for QueueIter<'a, T> +impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -204,7 +228,7 @@ where } let item = self - .queue + .deque .get_at(self.storage, self.end.wrapping_sub(1)) // end points to position after last element .transpose()?; self.end = self.end.wrapping_sub(1); @@ -212,7 +236,7 @@ where Some(item) } - // see [`QueueIter::nth`] + // see [`DequeIter::nth`] fn nth_back(&mut self, n: usize) -> Option { // make sure that we don't skip past the start if self.end.wrapping_sub(self.start) < n as u32 { @@ -226,68 +250,77 @@ where } #[cfg(test)] mod tests { - use crate::queue::Queue; + use crate::deque::Deque; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::StdResult; #[test] fn push_and_pop() { - const PEOPLE: Queue = Queue::new("people"); + const PEOPLE: Deque = Deque::new("people"); let mut store = MockStorage::new(); // push some entries - PEOPLE.push(&mut store, &"jack".to_owned()).unwrap(); - PEOPLE.push(&mut store, &"john".to_owned()).unwrap(); - PEOPLE.push(&mut store, &"joanne".to_owned()).unwrap(); + PEOPLE.push_back(&mut store, &"jack".to_owned()).unwrap(); + PEOPLE.push_back(&mut store, &"john".to_owned()).unwrap(); + PEOPLE.push_back(&mut store, &"joanne".to_owned()).unwrap(); // pop them, should be in correct order - assert_eq!("jack", PEOPLE.pop(&mut store).unwrap().unwrap()); - assert_eq!("john", PEOPLE.pop(&mut store).unwrap().unwrap()); + assert_eq!("jack", PEOPLE.pop_front(&mut store).unwrap().unwrap()); + assert_eq!("john", PEOPLE.pop_front(&mut store).unwrap().unwrap()); // push again in-between - PEOPLE.push(&mut store, &"jason".to_owned()).unwrap(); + PEOPLE.push_back(&mut store, &"jason".to_owned()).unwrap(); // pop last person from first batch - assert_eq!("joanne", PEOPLE.pop(&mut store).unwrap().unwrap()); + assert_eq!("joanne", PEOPLE.pop_front(&mut store).unwrap().unwrap()); // pop the entry pushed in-between - assert_eq!("jason", PEOPLE.pop(&mut store).unwrap().unwrap()); + assert_eq!("jason", PEOPLE.pop_front(&mut store).unwrap().unwrap()); // nothing after that - assert_eq!(None, PEOPLE.pop(&mut store).unwrap()); + assert_eq!(None, PEOPLE.pop_front(&mut store).unwrap()); + + // now push to the front + PEOPLE.push_front(&mut store, &"pascal".to_owned()).unwrap(); + PEOPLE.push_front(&mut store, &"peter".to_owned()).unwrap(); + PEOPLE.push_front(&mut store, &"paul".to_owned()).unwrap(); + + assert_eq!("pascal", PEOPLE.pop_back(&mut store).unwrap().unwrap()); + assert_eq!("paul", PEOPLE.pop_front(&mut store).unwrap().unwrap()); + assert_eq!("peter", PEOPLE.pop_back(&mut store).unwrap().unwrap()); } #[test] fn length() { - let queue: Queue = Queue::new("test"); + let queue: Deque = Deque::new("test"); let mut store = MockStorage::new(); assert_eq!(queue.len(&store).unwrap(), 0); assert_eq!(queue.is_empty(&store).unwrap(), true); // push some entries - queue.push(&mut store, &1234).unwrap(); - queue.push(&mut store, &2345).unwrap(); - queue.push(&mut store, &3456).unwrap(); - queue.push(&mut store, &4567).unwrap(); + queue.push_back(&mut store, &1234).unwrap(); + queue.push_back(&mut store, &2345).unwrap(); + queue.push_back(&mut store, &3456).unwrap(); + queue.push_back(&mut store, &4567).unwrap(); assert_eq!(queue.len(&store).unwrap(), 4); assert_eq!(queue.is_empty(&store).unwrap(), false); // pop some - queue.pop(&mut store).unwrap(); - queue.pop(&mut store).unwrap(); - queue.pop(&mut store).unwrap(); + queue.pop_front(&mut store).unwrap(); + queue.pop_front(&mut store).unwrap(); + queue.pop_front(&mut store).unwrap(); assert_eq!(queue.len(&store).unwrap(), 1); assert_eq!(queue.is_empty(&store).unwrap(), false); // pop the last one - queue.pop(&mut store).unwrap(); + queue.pop_front(&mut store).unwrap(); assert_eq!(queue.len(&store).unwrap(), 0); assert_eq!(queue.is_empty(&store).unwrap(), true); // should stay 0 after that - queue.pop(&mut store).unwrap(); + queue.pop_front(&mut store).unwrap(); assert_eq!( queue.len(&store).unwrap(), 0, @@ -298,14 +331,14 @@ mod tests { #[test] fn iterator() { - let queue: Queue = Queue::new("test"); + let queue: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items - queue.push(&mut store, &1).unwrap(); - queue.push(&mut store, &2).unwrap(); - queue.push(&mut store, &3).unwrap(); - queue.push(&mut store, &4).unwrap(); + queue.push_back(&mut store, &1).unwrap(); + queue.push_back(&mut store, &2).unwrap(); + queue.push_back(&mut store, &3).unwrap(); + queue.push_back(&mut store, &4).unwrap(); let items: StdResult> = queue.iter(&mut store).unwrap().collect(); assert_eq!(items.unwrap(), [1, 2, 3, 4]); @@ -323,14 +356,14 @@ mod tests { #[test] fn reverse_iterator() { - let queue: Queue = Queue::new("test"); + let queue: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items - queue.push(&mut store, &1).unwrap(); - queue.push(&mut store, &2).unwrap(); - queue.push(&mut store, &3).unwrap(); - queue.push(&mut store, &4).unwrap(); + queue.push_back(&mut store, &1).unwrap(); + queue.push_back(&mut store, &2).unwrap(); + queue.push_back(&mut store, &3).unwrap(); + queue.push_back(&mut store, &4).unwrap(); let items: StdResult> = queue.iter(&mut store).unwrap().rev().collect(); assert_eq!(items.unwrap(), [4, 3, 2, 1]); @@ -357,7 +390,7 @@ mod tests { #[test] fn wrapping() { - let queue: Queue = Queue::new("test"); + let queue: Deque = Deque::new("test"); let mut store = MockStorage::new(); // simulate queue that was pushed and popped `u32::MAX` times @@ -365,18 +398,18 @@ mod tests { queue.set_tail(&mut store, u32::MAX); // should be empty - assert_eq!(queue.pop(&mut store).unwrap(), None); + assert_eq!(queue.pop_front(&mut store).unwrap(), None); assert_eq!(queue.len(&store).unwrap(), 0); // pushing should still work - queue.push(&mut store, &1).unwrap(); + queue.push_back(&mut store, &1).unwrap(); assert_eq!( queue.len(&store).unwrap(), 1, "length should calculate correctly, even when wrapping" ); assert_eq!( - queue.pop(&mut store).unwrap(), + queue.pop_front(&mut store).unwrap(), Some(1), "popping should work, even when wrapping" ); @@ -384,11 +417,11 @@ mod tests { queue.set_head(&mut store, u32::MAX); queue.set_tail(&mut store, u32::MAX); - queue.push(&mut store, &1).unwrap(); - queue.push(&mut store, &2).unwrap(); - queue.push(&mut store, &3).unwrap(); - queue.push(&mut store, &4).unwrap(); - queue.push(&mut store, &5).unwrap(); + queue.push_back(&mut store, &1).unwrap(); + queue.push_back(&mut store, &2).unwrap(); + queue.push_back(&mut store, &3).unwrap(); + queue.push_back(&mut store, &4).unwrap(); + queue.push_back(&mut store, &5).unwrap(); let mut iter = queue.iter(&store).unwrap(); assert_eq!(iter.next().unwrap().unwrap(), 1); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 67b2e9e0b..b9b65f806 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -1,5 +1,6 @@ mod bound; mod de; +mod deque; mod endian; mod helpers; mod indexed_map; @@ -12,12 +13,14 @@ mod keys; mod map; mod path; mod prefix; -mod queue; mod snapshot; #[cfg(feature = "iterator")] pub use bound::{Bound, Bounder, PrefixBound, RawBound}; pub use de::KeyDeserialize; +pub use deque::Deque; +#[cfg(feature = "iterator")] +pub use deque::DequeIter; pub use endian::Endian; #[cfg(feature = "iterator")] pub use indexed_map::{IndexList, IndexedMap}; @@ -36,9 +39,6 @@ pub use map::Map; pub use path::Path; #[cfg(feature = "iterator")] pub use prefix::{range_with_prefix, Prefix}; -pub use queue::Queue; -#[cfg(feature = "iterator")] -pub use queue::QueueIter; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; From 4c325b56fd5d4f814a55c2891e20fd041fb5c5d8 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 12:26:59 +0200 Subject: [PATCH 469/631] Add missing feature checks --- packages/storage-plus/src/deque.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 3366fd335..d0395eb95 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -180,6 +180,7 @@ where end: u32, } +#[cfg(feature = "iterator")] impl<'a, T> Iterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, @@ -218,6 +219,7 @@ where } } +#[cfg(feature = "iterator")] impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, From 9982a4670bd689d8eaa12b9d9ff60355ca4c82f5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 12:50:45 +0200 Subject: [PATCH 470/631] Add front and back methods to deque --- packages/storage-plus/src/deque.rs | 170 +++++++++++++++++------------ 1 file changed, 101 insertions(+), 69 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index d0395eb95..756490f0e 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -9,7 +9,7 @@ use crate::helpers::{may_deserialize, namespaces_with_key}; const TAIL_KEY: &[u8] = b"t"; const HEAD_KEY: &[u8] = b"h"; -/// A queue stores multiple items at the given key. It provides efficient FIFO access. +/// A deque stores multiple items at the given key. It provides efficient FIFO and LIFO access. pub struct Deque<'a, T> { // prefix of the deque items namespace: &'a [u8], @@ -31,7 +31,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // save value let pos = self.tail(storage)?; - self.set_at(storage, pos, value)?; + self.set_at_unchecked(storage, pos, value)?; // update tail self.set_tail(storage, pos.wrapping_add(1)); @@ -42,7 +42,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn push_front(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // need to subtract first, because head potentially points to existing element let pos = self.head(storage)?.wrapping_sub(1); - self.set_at(storage, pos, value)?; + self.set_at_unchecked(storage, pos, value)?; // update head self.set_head(storage, pos); @@ -53,9 +53,9 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn pop_back(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.tail(storage)?.wrapping_sub(1); - let value = self.get_at(storage, pos)?; + let value = self.get_at_unchecked(storage, pos)?; if value.is_some() { - self.remove_at(storage, pos); + self.remove_at_unchecked(storage, pos); // only update tail if a value was popped self.set_tail(storage, pos); } @@ -66,15 +66,27 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn pop_front(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.head(storage)?; - let value = self.get_at(storage, pos)?; + let value = self.get_at_unchecked(storage, pos)?; if value.is_some() { - self.remove_at(storage, pos); + self.remove_at_unchecked(storage, pos); // only update head if a value was popped self.set_head(storage, pos.wrapping_add(1)); } Ok(value) } + /// Returns the first element of the deque without removing it + pub fn front(&self, storage: &dyn Storage) -> StdResult> { + let pos = self.head(storage)?; + self.get_at_unchecked(storage, pos) + } + + /// Returns the first element of the deque without removing it + pub fn back(&self, storage: &dyn Storage) -> StdResult> { + let pos = self.tail(storage)?.wrapping_sub(1); + self.get_at_unchecked(storage, pos) + } + /// Gets the length of the deque. pub fn len(&self, storage: &dyn Storage) -> StdResult { Ok(self.tail(storage)?.wrapping_sub(self.head(storage)?)) @@ -134,22 +146,22 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { } /// Tries to get the value at the given position (without bounds checking) - /// Used internally when popping - fn get_at(&self, storage: &dyn Storage, pos: u32) -> StdResult> { + /// Used internally + fn get_at_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); may_deserialize(&storage.get(&prefixed_key)) } /// Removes the value at the given position - /// Used internally when popping - fn remove_at(&self, storage: &mut dyn Storage, pos: u32) { + /// Used internally + fn remove_at_unchecked(&self, storage: &mut dyn Storage, pos: u32) { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); storage.remove(&prefixed_key); } /// Tries to set the value at the given position (without bounds checking) /// Used internally when pushing - fn set_at(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { + fn set_at_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); storage.set(&prefixed_key, &to_vec(value)?); @@ -192,7 +204,10 @@ where return None; } - let item = self.deque.get_at(self.storage, self.start).transpose()?; + let item = self + .deque + .get_at_unchecked(self.storage, self.start) + .transpose()?; self.start = self.start.wrapping_add(1); Some(item) @@ -231,7 +246,7 @@ where let item = self .deque - .get_at(self.storage, self.end.wrapping_sub(1)) // end points to position after last element + .get_at_unchecked(self.storage, self.end.wrapping_sub(1)) // end points to position after last element .transpose()?; self.end = self.end.wrapping_sub(1); @@ -295,93 +310,93 @@ mod tests { #[test] fn length() { - let queue: Deque = Deque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); - assert_eq!(queue.len(&store).unwrap(), 0); - assert_eq!(queue.is_empty(&store).unwrap(), true); + assert_eq!(deque.len(&store).unwrap(), 0); + assert_eq!(deque.is_empty(&store).unwrap(), true); // push some entries - queue.push_back(&mut store, &1234).unwrap(); - queue.push_back(&mut store, &2345).unwrap(); - queue.push_back(&mut store, &3456).unwrap(); - queue.push_back(&mut store, &4567).unwrap(); - assert_eq!(queue.len(&store).unwrap(), 4); - assert_eq!(queue.is_empty(&store).unwrap(), false); + deque.push_front(&mut store, &1234).unwrap(); + deque.push_back(&mut store, &2345).unwrap(); + deque.push_front(&mut store, &3456).unwrap(); + deque.push_back(&mut store, &4567).unwrap(); + assert_eq!(deque.len(&store).unwrap(), 4); + assert_eq!(deque.is_empty(&store).unwrap(), false); // pop some - queue.pop_front(&mut store).unwrap(); - queue.pop_front(&mut store).unwrap(); - queue.pop_front(&mut store).unwrap(); - assert_eq!(queue.len(&store).unwrap(), 1); - assert_eq!(queue.is_empty(&store).unwrap(), false); + deque.pop_front(&mut store).unwrap(); + deque.pop_back(&mut store).unwrap(); + deque.pop_front(&mut store).unwrap(); + assert_eq!(deque.len(&store).unwrap(), 1); + assert_eq!(deque.is_empty(&store).unwrap(), false); // pop the last one - queue.pop_front(&mut store).unwrap(); - assert_eq!(queue.len(&store).unwrap(), 0); - assert_eq!(queue.is_empty(&store).unwrap(), true); + deque.pop_front(&mut store).unwrap(); + assert_eq!(deque.len(&store).unwrap(), 0); + assert_eq!(deque.is_empty(&store).unwrap(), true); // should stay 0 after that - queue.pop_front(&mut store).unwrap(); + assert_eq!(deque.pop_back(&mut store).unwrap(), None); assert_eq!( - queue.len(&store).unwrap(), + deque.len(&store).unwrap(), 0, - "popping from empty queue should keep length 0" + "popping from empty deque should keep length 0" ); - assert_eq!(queue.is_empty(&store).unwrap(), true); + assert_eq!(deque.is_empty(&store).unwrap(), true); } #[test] fn iterator() { - let queue: Deque = Deque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items - queue.push_back(&mut store, &1).unwrap(); - queue.push_back(&mut store, &2).unwrap(); - queue.push_back(&mut store, &3).unwrap(); - queue.push_back(&mut store, &4).unwrap(); + deque.push_back(&mut store, &1).unwrap(); + deque.push_back(&mut store, &2).unwrap(); + deque.push_back(&mut store, &3).unwrap(); + deque.push_back(&mut store, &4).unwrap(); - let items: StdResult> = queue.iter(&mut store).unwrap().collect(); + let items: StdResult> = deque.iter(&mut store).unwrap().collect(); assert_eq!(items.unwrap(), [1, 2, 3, 4]); // nth should work correctly - let mut iter = queue.iter(&mut store).unwrap(); + let mut iter = deque.iter(&mut store).unwrap(); assert_eq!(iter.nth(6), None); assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); assert_eq!(iter.next(), None); - let mut iter = queue.iter(&mut store).unwrap(); + let mut iter = deque.iter(&mut store).unwrap(); assert_eq!(iter.nth(1).unwrap().unwrap(), 2); assert_eq!(iter.next().unwrap().unwrap(), 3); } #[test] fn reverse_iterator() { - let queue: Deque = Deque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items - queue.push_back(&mut store, &1).unwrap(); - queue.push_back(&mut store, &2).unwrap(); - queue.push_back(&mut store, &3).unwrap(); - queue.push_back(&mut store, &4).unwrap(); + deque.push_back(&mut store, &1).unwrap(); + deque.push_back(&mut store, &2).unwrap(); + deque.push_back(&mut store, &3).unwrap(); + deque.push_back(&mut store, &4).unwrap(); - let items: StdResult> = queue.iter(&mut store).unwrap().rev().collect(); + let items: StdResult> = deque.iter(&mut store).unwrap().rev().collect(); assert_eq!(items.unwrap(), [4, 3, 2, 1]); // nth should work correctly - let mut iter = queue.iter(&mut store).unwrap(); + let mut iter = deque.iter(&mut store).unwrap(); assert_eq!(iter.nth_back(6), None); assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); assert_eq!(iter.next_back(), None); - let mut iter = queue.iter(&mut store).unwrap().rev(); + let mut iter = deque.iter(&mut store).unwrap().rev(); assert_eq!(iter.nth(1).unwrap().unwrap(), 3); assert_eq!(iter.next().unwrap().unwrap(), 2); // mixed - let mut iter = queue.iter(&mut store).unwrap(); + let mut iter = deque.iter(&mut store).unwrap(); assert_eq!(iter.next().unwrap().unwrap(), 1); assert_eq!(iter.next_back().unwrap().unwrap(), 4); assert_eq!(iter.next_back().unwrap().unwrap(), 3); @@ -392,40 +407,40 @@ mod tests { #[test] fn wrapping() { - let queue: Deque = Deque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); - // simulate queue that was pushed and popped `u32::MAX` times - queue.set_head(&mut store, u32::MAX); - queue.set_tail(&mut store, u32::MAX); + // simulate deque that was pushed and popped `u32::MAX` times + deque.set_head(&mut store, u32::MAX); + deque.set_tail(&mut store, u32::MAX); // should be empty - assert_eq!(queue.pop_front(&mut store).unwrap(), None); - assert_eq!(queue.len(&store).unwrap(), 0); + assert_eq!(deque.pop_front(&mut store).unwrap(), None); + assert_eq!(deque.len(&store).unwrap(), 0); // pushing should still work - queue.push_back(&mut store, &1).unwrap(); + deque.push_back(&mut store, &1).unwrap(); assert_eq!( - queue.len(&store).unwrap(), + deque.len(&store).unwrap(), 1, "length should calculate correctly, even when wrapping" ); assert_eq!( - queue.pop_front(&mut store).unwrap(), + deque.pop_front(&mut store).unwrap(), Some(1), "popping should work, even when wrapping" ); - queue.set_head(&mut store, u32::MAX); - queue.set_tail(&mut store, u32::MAX); + deque.set_head(&mut store, u32::MAX); + deque.set_tail(&mut store, u32::MAX); - queue.push_back(&mut store, &1).unwrap(); - queue.push_back(&mut store, &2).unwrap(); - queue.push_back(&mut store, &3).unwrap(); - queue.push_back(&mut store, &4).unwrap(); - queue.push_back(&mut store, &5).unwrap(); + deque.push_back(&mut store, &1).unwrap(); + deque.push_back(&mut store, &2).unwrap(); + deque.push_back(&mut store, &3).unwrap(); + deque.push_back(&mut store, &4).unwrap(); + deque.push_back(&mut store, &5).unwrap(); - let mut iter = queue.iter(&store).unwrap(); + let mut iter = deque.iter(&store).unwrap(); assert_eq!(iter.next().unwrap().unwrap(), 1); assert_eq!(iter.next().unwrap().unwrap(), 2); assert_eq!(iter.next_back().unwrap().unwrap(), 5); @@ -433,4 +448,21 @@ mod tests { assert_eq!(iter.nth(1), None); assert_eq!(iter.start, iter.end); } + + #[test] + fn front_back() { + let deque: Deque = Deque::new("test"); + let mut store = MockStorage::new(); + + assert_eq!(deque.back(&store).unwrap(), None); + deque.push_back(&mut store, &1).unwrap(); + assert_eq!(deque.back(&store).unwrap(), Some(1)); + assert_eq!(deque.front(&store).unwrap(), Some(1)); + deque.push_back(&mut store, &2).unwrap(); + assert_eq!(deque.back(&store).unwrap(), Some(2)); + assert_eq!(deque.front(&store).unwrap(), Some(1)); + deque.push_front(&mut store, &3).unwrap(); + assert_eq!(deque.back(&store).unwrap(), Some(2)); + assert_eq!(deque.front(&store).unwrap(), Some(3)); + } } From c2062cb7ebce26eb3278260543ea5a09aaf6e7e5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 14:07:20 +0200 Subject: [PATCH 471/631] Add deque to readme --- packages/storage-plus/README.md | 63 ++++++++++++++++++++++++++++++ packages/storage-plus/src/deque.rs | 59 +++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index a47823688..f192e2578 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -635,3 +635,66 @@ In the particular case of `MultiIndex`, the primary key (`PK`) type parameter al the index key (the part that corresponds to the primary key, that is). So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. + +## Deque + +The usage of a [`Deque`](./src/deque.rs) is pretty straight-forward. +Conceptually it works like a storage-backed `VecDeque`and can be used as a queue or stack. +It allows you to push and pop elements on both ends and also read the first or last element without mutating the deque. + +Example Usage: + +```rust +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +struct Data { + pub name: String, + pub age: i32, +} + +const DATA: Deque = Deque::new("data"); + +fn demo() -> StdResult<()> { + let mut store = MockStorage::new(); + + // read methods return Option, so None if the deque is empty + let empty = DATA.front(&store)?; + assert_eq!(None, empty); + + // some example entries + let p1 = Data { + name: "admin".to_string(), + age: 1234, + }; + let p2 = Data { + name: "user".to_string(), + age: 123, + }; + + // use it like a queue by pushing and popping at opposite ends + DATA.push_back(&mut store, &p1)?; + DATA.push_back(&mut store, &p2)?; + + let admin = DATA.pop_front(&mut store)?; + assert_eq!(admin.as_ref(), Some(&p1)); + let user = DATA.pop_front(&mut store)?; + assert_eq!(user.as_ref(), Some(&p2)); + + // or push and pop at the same end to use it as a stack + DATA.push_back(&mut store, &p1)?; + DATA.push_back(&mut store, &p2)?; + + let user = DATA.pop_back(&mut store)?; + assert_eq!(user.as_ref(), Some(&p2)); + let admin = DATA.pop_back(&mut store)?; + assert_eq!(admin.as_ref(), Some(&p1)); + + // you can also iterate over it + DATA.push_front(&mut store, &p1)?; + DATA.push_front(&mut store, &p2)?; + + let all: StdResult> = DATA.iter(&store)?.collect(); + assert_eq!(all?, [p2, p1]); + + Ok(()) +} +``` \ No newline at end of file diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 756490f0e..78bcef8b2 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -145,7 +145,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { storage.set(&full_key, &value.to_be_bytes()); } - /// Tries to get the value at the given position (without bounds checking) + /// Tries to get the value at the given position /// Used internally fn get_at_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); @@ -159,7 +159,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { storage.remove(&prefixed_key); } - /// Tries to set the value at the given position (without bounds checking) + /// Tries to set the value at the given position /// Used internally when pushing fn set_at_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); @@ -271,6 +271,7 @@ mod tests { use cosmwasm_std::testing::MockStorage; use cosmwasm_std::StdResult; + use serde::{Deserialize, Serialize}; #[test] fn push_and_pop() { @@ -465,4 +466,58 @@ mod tests { assert_eq!(deque.back(&store).unwrap(), Some(2)); assert_eq!(deque.front(&store).unwrap(), Some(3)); } + + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Data { + pub name: String, + pub age: i32, + } + + const DATA: Deque = Deque::new("data"); + + #[test] + fn readme_works() -> StdResult<()> { + let mut store = MockStorage::new(); + + // read methods return Option, so None if the deque is empty + let empty = DATA.front(&store)?; + assert_eq!(None, empty); + + // some example entries + let p1 = Data { + name: "admin".to_string(), + age: 1234, + }; + let p2 = Data { + name: "user".to_string(), + age: 123, + }; + + // use it like a queue by pushing and popping at opposite ends + DATA.push_back(&mut store, &p1)?; + DATA.push_back(&mut store, &p2)?; + + let admin = DATA.pop_front(&mut store)?; + assert_eq!(admin.as_ref(), Some(&p1)); + let user = DATA.pop_front(&mut store)?; + assert_eq!(user.as_ref(), Some(&p2)); + + // or push and pop at the same end to use it as a stack + DATA.push_back(&mut store, &p1)?; + DATA.push_back(&mut store, &p2)?; + + let user = DATA.pop_back(&mut store)?; + assert_eq!(user.as_ref(), Some(&p2)); + let admin = DATA.pop_back(&mut store)?; + assert_eq!(admin.as_ref(), Some(&p1)); + + // you can also iterate over it + DATA.push_front(&mut store, &p1)?; + DATA.push_front(&mut store, &p2)?; + + let all: StdResult> = DATA.iter(&store)?.collect(); + assert_eq!(all?, [p2, p1]); + + Ok(()) + } } From f36e920f4a57bb6c4034ea91bba43c2f68bb36e4 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 14:59:20 +0200 Subject: [PATCH 472/631] Fix tests --- packages/storage-plus/src/deque.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 78bcef8b2..0c0f6f395 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -348,6 +348,7 @@ mod tests { } #[test] + #[cfg(feature = "iterator")] fn iterator() { let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); @@ -373,6 +374,7 @@ mod tests { } #[test] + #[cfg(feature = "iterator")] fn reverse_iterator() { let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); @@ -431,6 +433,13 @@ mod tests { Some(1), "popping should work, even when wrapping" ); + } + + #[test] + #[cfg(feature = "iterator")] + fn wrapping_iterator() { + let deque: Deque = Deque::new("test"); + let mut store = MockStorage::new(); deque.set_head(&mut store, u32::MAX); deque.set_tail(&mut store, u32::MAX); @@ -476,6 +485,7 @@ mod tests { const DATA: Deque = Deque::new("data"); #[test] + #[cfg(feature = "iterator")] fn readme_works() -> StdResult<()> { let mut store = MockStorage::new(); From 420cce8605a1050583efe281b9e6e6d86d890dfc Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 26 Sep 2022 15:06:08 +0200 Subject: [PATCH 473/631] Fix lints --- packages/storage-plus/src/deque.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 0c0f6f395..58f5935a5 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -88,6 +88,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { } /// Gets the length of the deque. + #[allow(clippy::len_without_is_empty)] pub fn len(&self, storage: &dyn Storage) -> StdResult { Ok(self.tail(storage)?.wrapping_sub(self.head(storage)?)) } @@ -315,7 +316,7 @@ mod tests { let mut store = MockStorage::new(); assert_eq!(deque.len(&store).unwrap(), 0); - assert_eq!(deque.is_empty(&store).unwrap(), true); + assert!(deque.is_empty(&store).unwrap()); // push some entries deque.push_front(&mut store, &1234).unwrap(); @@ -323,19 +324,19 @@ mod tests { deque.push_front(&mut store, &3456).unwrap(); deque.push_back(&mut store, &4567).unwrap(); assert_eq!(deque.len(&store).unwrap(), 4); - assert_eq!(deque.is_empty(&store).unwrap(), false); + assert!(!deque.is_empty(&store).unwrap()); // pop some deque.pop_front(&mut store).unwrap(); deque.pop_back(&mut store).unwrap(); deque.pop_front(&mut store).unwrap(); assert_eq!(deque.len(&store).unwrap(), 1); - assert_eq!(deque.is_empty(&store).unwrap(), false); + assert!(!deque.is_empty(&store).unwrap()); // pop the last one deque.pop_front(&mut store).unwrap(); assert_eq!(deque.len(&store).unwrap(), 0); - assert_eq!(deque.is_empty(&store).unwrap(), true); + assert!(deque.is_empty(&store).unwrap()); // should stay 0 after that assert_eq!(deque.pop_back(&mut store).unwrap(), None); @@ -344,7 +345,7 @@ mod tests { 0, "popping from empty deque should keep length 0" ); - assert_eq!(deque.is_empty(&store).unwrap(), true); + assert!(deque.is_empty(&store).unwrap()); } #[test] @@ -359,16 +360,16 @@ mod tests { deque.push_back(&mut store, &3).unwrap(); deque.push_back(&mut store, &4).unwrap(); - let items: StdResult> = deque.iter(&mut store).unwrap().collect(); + let items: StdResult> = deque.iter(&store).unwrap().collect(); assert_eq!(items.unwrap(), [1, 2, 3, 4]); // nth should work correctly - let mut iter = deque.iter(&mut store).unwrap(); + let mut iter = deque.iter(&store).unwrap(); assert_eq!(iter.nth(6), None); assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); assert_eq!(iter.next(), None); - let mut iter = deque.iter(&mut store).unwrap(); + let mut iter = deque.iter(&store).unwrap(); assert_eq!(iter.nth(1).unwrap().unwrap(), 2); assert_eq!(iter.next().unwrap().unwrap(), 3); } @@ -385,21 +386,21 @@ mod tests { deque.push_back(&mut store, &3).unwrap(); deque.push_back(&mut store, &4).unwrap(); - let items: StdResult> = deque.iter(&mut store).unwrap().rev().collect(); + let items: StdResult> = deque.iter(&store).unwrap().rev().collect(); assert_eq!(items.unwrap(), [4, 3, 2, 1]); // nth should work correctly - let mut iter = deque.iter(&mut store).unwrap(); + let mut iter = deque.iter(&store).unwrap(); assert_eq!(iter.nth_back(6), None); assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); assert_eq!(iter.next_back(), None); - let mut iter = deque.iter(&mut store).unwrap().rev(); + let mut iter = deque.iter(&store).unwrap().rev(); assert_eq!(iter.nth(1).unwrap().unwrap(), 3); assert_eq!(iter.next().unwrap().unwrap(), 2); // mixed - let mut iter = deque.iter(&mut store).unwrap(); + let mut iter = deque.iter(&store).unwrap(); assert_eq!(iter.next().unwrap().unwrap(), 1); assert_eq!(iter.next_back().unwrap().unwrap(), 4); assert_eq!(iter.next_back().unwrap().unwrap(), 3); From 19bb5cd8615a9867fe0c4e14e4ff73470fece7f5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 09:37:53 +0200 Subject: [PATCH 474/631] Throw error instead of silently ending iterator --- packages/storage-plus/src/deque.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 58f5935a5..72fe668f9 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -1,4 +1,4 @@ -use std::{convert::TryInto, marker::PhantomData}; +use std::{any::type_name, convert::TryInto, marker::PhantomData}; use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; use serde::{de::DeserializeOwned, Serialize}; @@ -208,7 +208,7 @@ where let item = self .deque .get_at_unchecked(self.storage, self.start) - .transpose()?; + .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); self.start = self.start.wrapping_add(1); Some(item) @@ -248,7 +248,7 @@ where let item = self .deque .get_at_unchecked(self.storage, self.end.wrapping_sub(1)) // end points to position after last element - .transpose()?; + .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); self.end = self.end.wrapping_sub(1); Some(item) From 7b8342d823cba319be4ec3a0dd9e1723dd599464 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 10:02:33 +0200 Subject: [PATCH 475/631] Rename methods --- packages/storage-plus/src/deque.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 72fe668f9..374df597c 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -31,7 +31,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // save value let pos = self.tail(storage)?; - self.set_at_unchecked(storage, pos, value)?; + self.set_unchecked(storage, pos, value)?; // update tail self.set_tail(storage, pos.wrapping_add(1)); @@ -42,7 +42,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn push_front(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // need to subtract first, because head potentially points to existing element let pos = self.head(storage)?.wrapping_sub(1); - self.set_at_unchecked(storage, pos, value)?; + self.set_unchecked(storage, pos, value)?; // update head self.set_head(storage, pos); @@ -53,9 +53,9 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn pop_back(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.tail(storage)?.wrapping_sub(1); - let value = self.get_at_unchecked(storage, pos)?; + let value = self.get_unchecked(storage, pos)?; if value.is_some() { - self.remove_at_unchecked(storage, pos); + self.remove_unchecked(storage, pos); // only update tail if a value was popped self.set_tail(storage, pos); } @@ -66,9 +66,9 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn pop_front(&self, storage: &mut dyn Storage) -> StdResult> { // get position let pos = self.head(storage)?; - let value = self.get_at_unchecked(storage, pos)?; + let value = self.get_unchecked(storage, pos)?; if value.is_some() { - self.remove_at_unchecked(storage, pos); + self.remove_unchecked(storage, pos); // only update head if a value was popped self.set_head(storage, pos.wrapping_add(1)); } @@ -78,13 +78,13 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { /// Returns the first element of the deque without removing it pub fn front(&self, storage: &dyn Storage) -> StdResult> { let pos = self.head(storage)?; - self.get_at_unchecked(storage, pos) + self.get_unchecked(storage, pos) } /// Returns the first element of the deque without removing it pub fn back(&self, storage: &dyn Storage) -> StdResult> { let pos = self.tail(storage)?.wrapping_sub(1); - self.get_at_unchecked(storage, pos) + self.get_unchecked(storage, pos) } /// Gets the length of the deque. @@ -148,21 +148,21 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { /// Tries to get the value at the given position /// Used internally - fn get_at_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { + fn get_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); may_deserialize(&storage.get(&prefixed_key)) } /// Removes the value at the given position /// Used internally - fn remove_at_unchecked(&self, storage: &mut dyn Storage, pos: u32) { + fn remove_unchecked(&self, storage: &mut dyn Storage, pos: u32) { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); storage.remove(&prefixed_key); } /// Tries to set the value at the given position /// Used internally when pushing - fn set_at_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { + fn set_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); storage.set(&prefixed_key, &to_vec(value)?); @@ -207,7 +207,7 @@ where let item = self .deque - .get_at_unchecked(self.storage, self.start) + .get_unchecked(self.storage, self.start) .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); self.start = self.start.wrapping_add(1); @@ -247,7 +247,7 @@ where let item = self .deque - .get_at_unchecked(self.storage, self.end.wrapping_sub(1)) // end points to position after last element + .get_unchecked(self.storage, self.end.wrapping_sub(1)) // end points to position after last element .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); self.end = self.end.wrapping_sub(1); From 82e843b74e71783bd501db96c9ea11b75caf653e Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 10:12:53 +0200 Subject: [PATCH 476/631] Fix docs --- packages/storage-plus/README.md | 4 ++-- packages/storage-plus/src/deque.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index f192e2578..e92069d2c 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -639,7 +639,7 @@ to be correctly defined, so that it matches the primary key type, or its (typica ## Deque The usage of a [`Deque`](./src/deque.rs) is pretty straight-forward. -Conceptually it works like a storage-backed `VecDeque`and can be used as a queue or stack. +Conceptually it works like a storage-backed version of Rust std's `VecDeque` and can be used as a queue or stack. It allows you to push and pop elements on both ends and also read the first or last element without mutating the deque. Example Usage: @@ -656,7 +656,7 @@ const DATA: Deque = Deque::new("data"); fn demo() -> StdResult<()> { let mut store = MockStorage::new(); - // read methods return Option, so None if the deque is empty + // read methods return a wrapped Option, so None if the deque is empty let empty = DATA.front(&store)?; assert_eq!(None, empty); diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 374df597c..42832f527 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -490,7 +490,7 @@ mod tests { fn readme_works() -> StdResult<()> { let mut store = MockStorage::new(); - // read methods return Option, so None if the deque is empty + // read methods return a wrapped Option, so None if the deque is empty let empty = DATA.front(&store)?; assert_eq!(None, empty); From 5592368e8a593d778864554ad2cb2edf6330d4e5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 11:02:59 +0200 Subject: [PATCH 477/631] Add test for iterator error --- packages/storage-plus/src/deque.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 42832f527..2842c7ba2 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -271,7 +271,7 @@ mod tests { use crate::deque::Deque; use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::StdResult; + use cosmwasm_std::{StdError, StdResult}; use serde::{Deserialize, Serialize}; #[test] @@ -531,4 +531,30 @@ mod tests { Ok(()) } + + #[test] + #[cfg(feature = "iterator")] + fn iterator_errors_when_item_missing() { + let mut store = MockStorage::new(); + + let deque = Deque::new("error_test"); + + deque.push_back(&mut store, &1u32).unwrap(); + // manually remove it + deque.remove_unchecked(&mut store, 0); + + let mut iter = deque.iter(&store).unwrap(); + + assert!( + matches!(iter.next(), Some(Err(StdError::NotFound { .. }))), + "iterator should error when item is missing" + ); + + let mut iter = deque.iter(&store).unwrap().rev(); + + assert!( + matches!(iter.next(), Some(Err(StdError::NotFound { .. }))), + "reverse iterator should error when item is missing" + ); + } } From 4616d332d863cad143b0317a8cb70516a3ff449e Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 11:03:03 +0200 Subject: [PATCH 478/631] Add documentation about max deque size --- packages/storage-plus/src/deque.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 2842c7ba2..d9115e637 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -10,6 +10,9 @@ const TAIL_KEY: &[u8] = b"t"; const HEAD_KEY: &[u8] = b"h"; /// A deque stores multiple items at the given key. It provides efficient FIFO and LIFO access. +/// +/// It has a maximum capacity of `u32::MAX - 1`. Make sure to never exceed that number when using this type. +/// If you do, the methods won't work as intended anymore. pub struct Deque<'a, T> { // prefix of the deque items namespace: &'a [u8], From b4f3fd34bc84c179b640515b3f9048ee6c2d15bb Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 12:13:10 +0200 Subject: [PATCH 479/631] Add random access to deque --- packages/storage-plus/src/deque.rs | 75 ++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index d9115e637..07bc84609 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -93,7 +93,7 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { /// Gets the length of the deque. #[allow(clippy::len_without_is_empty)] pub fn len(&self, storage: &dyn Storage) -> StdResult { - Ok(self.tail(storage)?.wrapping_sub(self.head(storage)?)) + Ok(calc_len(self.head(storage)?, self.tail(storage)?)) } /// Returns `true` if the deque contains no elements. @@ -149,6 +149,22 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { storage.set(&full_key, &value.to_be_bytes()); } + /// Returns the value at the given position in the queue or `None` if the index is out of bounds + pub fn get(&self, storage: &dyn Storage, pos: u32) -> StdResult> { + let head = self.head(storage)?; + let tail = self.tail(storage)?; + + if pos >= calc_len(head, tail) { + // out of bounds + return Ok(None); + } + + let pos = head.wrapping_add(pos); + self.get_unchecked(storage, pos) + .and_then(|v| v.ok_or_else(|| StdError::not_found(format!("deque position {}", pos)))) + .map(Some) + } + /// Tries to get the value at the given position /// Used internally fn get_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { @@ -173,6 +189,12 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { } } +// used internally to avoid additional storage loads +#[inline] +fn calc_len(head: u32, tail: u32) -> u32 { + tail.wrapping_sub(head) +} + #[cfg(feature = "iterator")] impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { @@ -218,7 +240,7 @@ where } fn size_hint(&self) -> (usize, Option) { - let len = self.end.wrapping_sub(self.start) as usize; + let len = calc_len(self.start, self.end) as usize; (len, Some(len)) } @@ -228,7 +250,7 @@ where // Once `advance_by` is stabilized, we can implement that instead (`nth` calls it internally). fn nth(&mut self, n: usize) -> Option { // make sure that we don't skip past the end - if self.end.wrapping_sub(self.start) < n as u32 { + if calc_len(self.start, self.end) < n as u32 { // mark as empty self.start = self.end; } else { @@ -260,7 +282,7 @@ where // see [`DequeIter::nth`] fn nth_back(&mut self, n: usize) -> Option { // make sure that we don't skip past the start - if self.end.wrapping_sub(self.start) < n as u32 { + if calc_len(self.start, self.end) < n as u32 { // mark as empty self.end = self.start; } else { @@ -560,4 +582,49 @@ mod tests { "reverse iterator should error when item is missing" ); } + + #[test] + fn get() { + let mut store = MockStorage::new(); + + let deque = Deque::new("test"); + + deque.push_back(&mut store, &1u32).unwrap(); + deque.push_back(&mut store, &2).unwrap(); + + assert_eq!(deque.get(&store, 0).unwrap(), Some(1)); + assert_eq!(deque.get(&store, 1).unwrap(), Some(2)); + assert_eq!( + deque.get(&store, 2).unwrap(), + None, + "out of bounds access should return None" + ); + + // manually remove storage item + deque.remove_unchecked(&mut store, 1); + + assert!( + matches!(deque.get(&store, 1), Err(StdError::NotFound { .. })), + "missing deque item should error" + ); + + // start fresh + let deque = Deque::new("test2"); + + deque.push_back(&mut store, &0u32).unwrap(); + deque.push_back(&mut store, &1).unwrap(); + // push to front to move the head index + deque.push_front(&mut store, &u32::MAX).unwrap(); + deque.push_front(&mut store, &(u32::MAX - 1)).unwrap(); + + assert_eq!(deque.get(&store, 0).unwrap().unwrap(), u32::MAX - 1); + assert_eq!(deque.get(&store, 1).unwrap().unwrap(), u32::MAX); + assert_eq!(deque.get(&store, 2).unwrap().unwrap(), 0); + assert_eq!(deque.get(&store, 3).unwrap().unwrap(), 1); + assert_eq!( + deque.get(&store, 5).unwrap(), + None, + "out of bounds access should return None" + ); + } } From 48561bfb65dc09f67dec0b574ba0cb00e520faaa Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 12:14:33 +0200 Subject: [PATCH 480/631] Rename Deque to VecDeque --- packages/storage-plus/src/deque.rs | 44 +++++++++++++++--------------- packages/storage-plus/src/lib.rs | 4 +-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 07bc84609..92ea1ebd6 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -13,14 +13,14 @@ const HEAD_KEY: &[u8] = b"h"; /// /// It has a maximum capacity of `u32::MAX - 1`. Make sure to never exceed that number when using this type. /// If you do, the methods won't work as intended anymore. -pub struct Deque<'a, T> { +pub struct VecDeque<'a, T> { // prefix of the deque items namespace: &'a [u8], // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed item_type: PhantomData, } -impl<'a, T> Deque<'a, T> { +impl<'a, T> VecDeque<'a, T> { pub const fn new(prefix: &'a str) -> Self { Self { namespace: prefix.as_bytes(), @@ -29,7 +29,7 @@ impl<'a, T> Deque<'a, T> { } } -impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { +impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { /// Adds the given value to the end of the deque pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // save value @@ -196,9 +196,9 @@ fn calc_len(head: u32, tail: u32) -> u32 { } #[cfg(feature = "iterator")] -impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { - pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { - Ok(DequeIter { +impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { + pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { + Ok(VecDequeIter { deque: self, storage, start: self.head(storage)?, @@ -208,18 +208,18 @@ impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { } #[cfg(feature = "iterator")] -pub struct DequeIter<'a, T> +pub struct VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, { - deque: &'a Deque<'a, T>, + deque: &'a VecDeque<'a, T>, storage: &'a dyn Storage, start: u32, end: u32, } #[cfg(feature = "iterator")] -impl<'a, T> Iterator for DequeIter<'a, T> +impl<'a, T> Iterator for VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -261,7 +261,7 @@ where } #[cfg(feature = "iterator")] -impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> +impl<'a, T> DoubleEndedIterator for VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -293,7 +293,7 @@ where } #[cfg(test)] mod tests { - use crate::deque::Deque; + use crate::deque::VecDeque; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{StdError, StdResult}; @@ -301,7 +301,7 @@ mod tests { #[test] fn push_and_pop() { - const PEOPLE: Deque = Deque::new("people"); + const PEOPLE: VecDeque = VecDeque::new("people"); let mut store = MockStorage::new(); // push some entries @@ -337,7 +337,7 @@ mod tests { #[test] fn length() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); assert_eq!(deque.len(&store).unwrap(), 0); @@ -376,7 +376,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] fn iterator() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); // push some items @@ -402,7 +402,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] fn reverse_iterator() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); // push some items @@ -436,7 +436,7 @@ mod tests { #[test] fn wrapping() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); // simulate deque that was pushed and popped `u32::MAX` times @@ -464,7 +464,7 @@ mod tests { #[test] #[cfg(feature = "iterator")] fn wrapping_iterator() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); deque.set_head(&mut store, u32::MAX); @@ -487,7 +487,7 @@ mod tests { #[test] fn front_back() { - let deque: Deque = Deque::new("test"); + let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); assert_eq!(deque.back(&store).unwrap(), None); @@ -508,7 +508,7 @@ mod tests { pub age: i32, } - const DATA: Deque = Deque::new("data"); + const DATA: VecDeque = VecDeque::new("data"); #[test] #[cfg(feature = "iterator")] @@ -562,7 +562,7 @@ mod tests { fn iterator_errors_when_item_missing() { let mut store = MockStorage::new(); - let deque = Deque::new("error_test"); + let deque = VecDeque::new("error_test"); deque.push_back(&mut store, &1u32).unwrap(); // manually remove it @@ -587,7 +587,7 @@ mod tests { fn get() { let mut store = MockStorage::new(); - let deque = Deque::new("test"); + let deque = VecDeque::new("test"); deque.push_back(&mut store, &1u32).unwrap(); deque.push_back(&mut store, &2).unwrap(); @@ -609,7 +609,7 @@ mod tests { ); // start fresh - let deque = Deque::new("test2"); + let deque = VecDeque::new("test2"); deque.push_back(&mut store, &0u32).unwrap(); deque.push_back(&mut store, &1).unwrap(); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index b9b65f806..014834bf8 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -18,9 +18,9 @@ mod snapshot; #[cfg(feature = "iterator")] pub use bound::{Bound, Bounder, PrefixBound, RawBound}; pub use de::KeyDeserialize; -pub use deque::Deque; +pub use deque::VecDeque; #[cfg(feature = "iterator")] -pub use deque::DequeIter; +pub use deque::VecDequeIter; pub use endian::Endian; #[cfg(feature = "iterator")] pub use indexed_map::{IndexList, IndexedMap}; From db6cab24ab8ac868a7a3aa333f259ac7b2d58b60 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 12:41:07 +0200 Subject: [PATCH 481/631] Update docs --- packages/storage-plus/README.md | 10 ++++++++-- packages/storage-plus/src/deque.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index e92069d2c..017dba7ba 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -636,11 +636,12 @@ the index key (the part that corresponds to the primary key, that is). So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. -## Deque +## VecDeque -The usage of a [`Deque`](./src/deque.rs) is pretty straight-forward. +The usage of a [`VecDeque`](./src/deque.rs) is pretty straight-forward. Conceptually it works like a storage-backed version of Rust std's `VecDeque` and can be used as a queue or stack. It allows you to push and pop elements on both ends and also read the first or last element without mutating the deque. +You can also read a specific index directly. Example Usage: @@ -695,6 +696,11 @@ fn demo() -> StdResult<()> { let all: StdResult> = DATA.iter(&store)?.collect(); assert_eq!(all?, [p2, p1]); + // or access an index directly + assert_eq!(DATA.get(&store, 0)?, Some(p2)); + assert_eq!(DATA.get(&store, 1)?, Some(p1)); + assert_eq!(DATA.get(&store, 3)?, None); + Ok(()) } ``` \ No newline at end of file diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 92ea1ebd6..6c51440cb 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -9,7 +9,8 @@ use crate::helpers::{may_deserialize, namespaces_with_key}; const TAIL_KEY: &[u8] = b"t"; const HEAD_KEY: &[u8] = b"h"; -/// A deque stores multiple items at the given key. It provides efficient FIFO and LIFO access. +/// A deque stores multiple items at the given key. It provides efficient FIFO and LIFO access, +/// as well as direct index access. /// /// It has a maximum capacity of `u32::MAX - 1`. Make sure to never exceed that number when using this type. /// If you do, the methods won't work as intended anymore. @@ -552,7 +553,12 @@ mod tests { DATA.push_front(&mut store, &p2)?; let all: StdResult> = DATA.iter(&store)?.collect(); - assert_eq!(all?, [p2, p1]); + assert_eq!(all?, [p2.clone(), p1.clone()]); + + // or access an index directly + assert_eq!(DATA.get(&store, 0)?, Some(p2)); + assert_eq!(DATA.get(&store, 1)?, Some(p1)); + assert_eq!(DATA.get(&store, 3)?, None); Ok(()) } From 6bf616a90e06edb3551c22d860974e6e8230e500 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 27 Sep 2022 13:35:34 +0200 Subject: [PATCH 482/631] Release 0.15.1 --- Cargo.lock | 42 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist-ng/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 +++---- contracts/cw1155-base/Cargo.toml | 10 +++--- contracts/cw20-base/Cargo.toml | 12 +++---- contracts/cw20-ics20/Cargo.toml | 12 +++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 +++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-macro/Cargo.toml | 4 +-- packages/storage-plus/Cargo.toml | 4 +-- packages/utils/Cargo.toml | 6 ++-- 22 files changed, 112 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab2efb6a7..93c0d63f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,7 +400,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -413,7 +413,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.15.0" +version = "0.15.1" dependencies = [ "anyhow", "cosmwasm-std", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "cw-storage-macro" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-std", "cw-storage-plus", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-std", "criterion", @@ -452,7 +452,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -467,7 +467,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -477,7 +477,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -494,7 +494,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.15.0" +version = "0.15.1" dependencies = [ "anyhow", "assert_matches", @@ -513,7 +513,7 @@ dependencies = [ [[package]] name = "cw1-whitelist-ng" -version = "0.15.0" +version = "0.15.1" dependencies = [ "anyhow", "assert_matches", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -558,7 +558,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -569,7 +569,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -597,7 +597,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -614,7 +614,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -625,7 +625,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -643,7 +643,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -662,7 +662,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.15.0" +version = "0.15.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 1048e93c6..3772c3c8a 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -20,16 +20,16 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw1 = { path = "../../packages/cw1", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.0", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw1 = { path = "../../packages/cw1", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.1", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml index 0835031d8..d47fbb8cf 100644 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ b/contracts/cw1-whitelist-ng/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist-ng" -version = "0.15.0" +version = "0.15.1" authors = ["Bartłomiej Kuras "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -23,19 +23,19 @@ multitest = ["cw-multi-test", "anyhow"] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw1 = { path = "../../packages/cw1", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw1 = { path = "../../packages/cw1", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0", optional = true } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1", optional = true } anyhow = { version = "1", optional = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } derivative = "2" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index cbccd3d4d..5c1f4a20a 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw1 = { path = "../../packages/cw1", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw1 = { path = "../../packages/cw1", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 1745a0bd7..efaddc066 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.15.0" +version = "0.15.1" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw1155 = { path = "../../packages/cw1155", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index e324af8a8..573521921 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw20 = { path = "../../packages/cw20", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw20 = { path = "../../packages/cw20", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 735223fe7..24ce3ddaa 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -19,12 +19,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw20 = { path = "../../packages/cw20", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw20 = { path = "../../packages/cw20", version = "0.15.1" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 32543b216..ab24b2784 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -19,16 +19,16 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw3 = { path = "../../packages/cw3", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw3 = { path = "../../packages/cw3", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "0.15.0" } -cw20-base = { path = "../cw20-base", version = "0.15.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } +cw20 = { path = "../../packages/cw20", version = "0.15.1" } +cw20-base = { path = "../cw20-base", version = "0.15.1", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index bb0d02102..1a0229d2c 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -19,17 +19,17 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw3 = { path = "../../packages/cw3", version = "0.15.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw3 = { path = "../../packages/cw3", version = "0.15.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.1", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "0.15.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.0" } +cw4-group = { path = "../cw4-group", version = "0.15.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index bfff7d61e..51cf9ea94 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw4 = { path = "../../packages/cw4", version = "0.15.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw4 = { path = "../../packages/cw4", version = "0.15.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 3e3c7b3b4..e454344e1 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw2 = { path = "../../packages/cw2", version = "0.15.0" } -cw4 = { path = "../../packages/cw4", version = "0.15.0" } -cw20 = { path = "../../packages/cw20", version = "0.15.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw4 = { path = "../../packages/cw4", version = "0.15.1" } +cw20 = { path = "../../packages/cw20", version = "0.15.1" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index b56979272..ed3ece2a7 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw-utils = { path = "../utils", version = "0.15.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.15.0" } +cw-utils = { path = "../utils", version = "0.15.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 7f52a2492..d3a15e52f 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 6a4888c4a..a0330db3a 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.15.0" +version = "0.15.1" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index f20c1c2d5..6863f21be 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 5bd8b7727..55e51de55 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index bb60c2b7f..e5f889fa8 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.0" } +cw-utils = { path = "../../packages/utils", version = "0.15.1" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 5a48db8bb..ccbc806ec 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.1" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 5092d993b..916ca0ef5 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -17,8 +17,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0"} +cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1"} cosmwasm-std = { version = "1.1.0", features = ["staking"] } cosmwasm-storage = "1.1.0" itertools = "0.10.1" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index a47530b77..48cd9537d 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-macro" -version = "0.15.0" +version = "0.15.1" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" description = "Macro helpers for storage-plus" @@ -16,6 +16,6 @@ proc-macro = true syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] -cw-storage-plus = { version = "<=0.15.0, >=0.14.0", path = "../storage-plus" } +cw-storage-plus = { version = "<=0.15.1, >=0.14.0", path = "../storage-plus" } cosmwasm-std = { version = "1.1.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 5ee6a66fa..7f453420a 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -21,7 +21,7 @@ bench = false cosmwasm-std = { version = "1.1.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.15.0", optional = true, path = "../storage-macro" } +cw-storage-macro = { version = "0.15.1", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = [ "html_reports" ] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index bf746cfeb..dbbcb9dc7 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.15.0" +version = "0.15.1" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -13,12 +13,12 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw2 = { path = "../../packages/cw2", version = "0.15.0" } +cw2 = { path = "../../packages/cw2", version = "0.15.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.21" [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } prost = "0.9" From 35847dee8218f83db55a94af58298c364dbe2f16 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 27 Sep 2022 15:39:19 +0200 Subject: [PATCH 483/631] Update CHANGELOG --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8322f8747..761849362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,20 @@ # Changelog -## [Unreleased](https://github.com/CosmWasm/cw-plus/tree/HEAD) +## [v0.15.1](https://github.com/CosmWasm/cw-plus/tree/v0.15.1) (2022-09-27) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.0...v0.15.1) + +**Closed issues:** + +- Add stack and queue implementations to storage-plus [\#776](https://github.com/CosmWasm/cw-plus/issues/776) + +**Merged pull requests:** + +- Release 0.15.1 [\#809](https://github.com/CosmWasm/cw-plus/pull/809) ([uint](https://github.com/uint)) +- Add Deque [\#807](https://github.com/CosmWasm/cw-plus/pull/807) ([chipshort](https://github.com/chipshort)) +- Cw1155-base public queries and move tests [\#804](https://github.com/CosmWasm/cw-plus/pull/804) ([ismellike](https://github.com/ismellike)) +- Add clear and is\_empty methods to Map [\#803](https://github.com/CosmWasm/cw-plus/pull/803) ([manu0466](https://github.com/manu0466)) +- SnapshotItem total, public query methods, and safe math [\#802](https://github.com/CosmWasm/cw-plus/pull/802) ([ismellike](https://github.com/ismellike)) ## [v0.15.0](https://github.com/CosmWasm/cw-plus/tree/v0.15.0) (2022-09-14) From 6be203ac4e7a8a7bfb994d5799095e864505d609 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 28 Sep 2022 14:29:49 +0200 Subject: [PATCH 484/631] Add update and clear admin support to multitest --- packages/multi-test/src/wasm.rs | 165 +++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 618e2739d..a6ec76bb8 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -327,6 +327,34 @@ where } } + /// unified logic for UpdateAdmin and ClearAdmin messages + fn update_admin( + &self, + api: &dyn Api, + storage: &mut dyn Storage, + sender: Addr, + contract_addr: &str, + new_admin: Option, + ) -> AnyResult { + let contract_addr = api.addr_validate(contract_addr)?; + let admin = new_admin.map(|a| api.addr_validate(&a)).transpose()?; + + // check admin status + let mut data = self.load_contract(storage, &contract_addr)?; + if data.admin != Some(sender) { + bail!("Only admin can clear contract admin: {:?}", data.admin); + } + // update admin field + data.admin = admin; + self.save_contract(storage, &contract_addr, &data)?; + + // no custom event here + Ok(AppResponse { + data: None, + events: vec![], + }) + } + // this returns the contract address as well, so we can properly resend the data fn execute_wasm( &self, @@ -474,6 +502,13 @@ where res.data = execute_response(res.data); Ok(res) } + WasmMsg::UpdateAdmin { + contract_addr, + admin, + } => self.update_admin(api, storage, sender, &contract_addr, Some(admin)), + WasmMsg::ClearAdmin { contract_addr } => { + self.update_admin(api, storage, sender, &contract_addr, None) + } msg => bail!(Error::UnsupportedWasmMsg(msg)), } } @@ -906,7 +941,8 @@ mod test { use crate::app::Router; use crate::bank::BankKeeper; use crate::module::FailingModule; - use crate::test_helpers::contracts::{error, payout}; + use crate::test_helpers::contracts::{caller, error, payout}; + use crate::test_helpers::EmptyMsg; use crate::transactions::StorageTransaction; use super::*; @@ -1356,4 +1392,131 @@ mod test { assert_payout(&keeper, &mut wasm_storage, &contract2, &payout2); assert_payout(&keeper, &mut wasm_storage, &contract3, &payout3); } + + fn assert_admin( + storage: &dyn Storage, + keeper: &WasmKeeper, + contract_addr: &impl ToString, + admin: Option, + ) { + let api = MockApi::default(); + let querier: MockQuerier = MockQuerier::new(&[]); + // query + let data = keeper + .query( + &api, + storage, + &querier, + &mock_env().block, + WasmQuery::ContractInfo { + contract_addr: contract_addr.to_string(), + }, + ) + .unwrap(); + let res: ContractInfoResponse = from_slice(&data).unwrap(); + assert_eq!(res.admin, admin.as_ref().map(Addr::to_string)); + } + + #[test] + fn update_clear_admin_works() { + let api = MockApi::default(); + let mut keeper = WasmKeeper::new(); + let block = mock_env().block; + let code_id = keeper.store_code(caller::contract()); + + let mut wasm_storage = MockStorage::new(); + + let admin: Addr = Addr::unchecked("admin"); + let new_admin: Addr = Addr::unchecked("new_admin"); + let normal_user: Addr = Addr::unchecked("normal_user"); + + let contract_addr = keeper + .register_contract( + &mut wasm_storage, + code_id, + Addr::unchecked("creator"), + admin.clone(), + "label".to_owned(), + 1000, + ) + .unwrap(); + + // init the contract + let info = mock_info("admin", &[]); + let init_msg = to_vec(&EmptyMsg {}).unwrap(); + let res = keeper + .call_instantiate( + contract_addr.clone(), + &api, + &mut wasm_storage, + &mock_router(), + &block, + info, + init_msg, + ) + .unwrap(); + assert_eq!(0, res.messages.len()); + + assert_admin(&wasm_storage, &keeper, &contract_addr, Some(admin.clone())); + + // non-admin should not be allowed to become admin on their own + keeper + .execute_wasm( + &api, + &mut wasm_storage, + &mock_router(), + &block, + normal_user.clone(), + WasmMsg::UpdateAdmin { + contract_addr: contract_addr.to_string(), + admin: normal_user.to_string(), + }, + ) + .unwrap_err(); + + // should still be admin + assert_admin(&wasm_storage, &keeper, &contract_addr, Some(admin.clone())); + + // admin should be allowed to transfers adminship + let res = keeper + .execute_wasm( + &api, + &mut wasm_storage, + &mock_router(), + &block, + admin.clone(), + WasmMsg::UpdateAdmin { + contract_addr: contract_addr.to_string(), + admin: new_admin.to_string(), + }, + ) + .unwrap(); + assert_eq!(res.events.len(), 0); + + // new_admin should now be admin + assert_admin( + &wasm_storage, + &keeper, + &contract_addr, + Some(new_admin.clone()), + ); + + // new_admin should now be able to clear to admin + let res = keeper + .execute_wasm( + &api, + &mut wasm_storage, + &mock_router(), + &block, + new_admin, + WasmMsg::ClearAdmin { + contract_addr: contract_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(res.events.len(), 0); + + // should have no admin now + assert_admin(&wasm_storage, &keeper, &contract_addr, None); + } } From 8963464b279934577adcc0f0a9d5669950291aa7 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 28 Sep 2022 14:30:16 +0200 Subject: [PATCH 485/631] Add test for update admin multitest --- packages/multi-test/src/app.rs | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 68995265c..f526712f1 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -1828,6 +1828,68 @@ mod test { assert_eq!(state.beneficiary, random); } + #[test] + fn send_update_admin_works() { + // The plan: + // create a hackatom contract + // check admin set properly + // update admin succeeds if admin + // update admin fails if not (new) admin + // check admin set properly + let owner = Addr::unchecked("owner"); + let owner2 = Addr::unchecked("owner2"); + let beneficiary = Addr::unchecked("beneficiary"); + + let mut app = App::default(); + + // create a hackatom contract with some funds + let contract_id = app.store_code(hackatom::contract()); + let contract = app + .instantiate_contract( + contract_id, + owner.clone(), + &hackatom::InstantiateMsg { + beneficiary: beneficiary.as_str().to_owned(), + }, + &[], + "Hackatom", + Some(owner.to_string()), + ) + .unwrap(); + + // check admin set properly + let info = app.contract_data(&contract).unwrap(); + assert_eq!(info.admin, Some(owner.clone())); + + // transfer adminship to owner2 + app.execute( + owner.clone(), + CosmosMsg::Wasm(WasmMsg::UpdateAdmin { + contract_addr: contract.to_string(), + admin: owner2.to_string(), + }), + ) + .unwrap(); + + // check admin set properly + let info = app.contract_data(&contract).unwrap(); + assert_eq!(info.admin, Some(owner2.clone())); + + // update admin fails if not owner2 + app.execute( + owner.clone(), + CosmosMsg::Wasm(WasmMsg::UpdateAdmin { + contract_addr: contract.to_string(), + admin: owner.to_string(), + }), + ) + .unwrap_err(); + + // check admin still the same + let info = app.contract_data(&contract).unwrap(); + assert_eq!(info.admin, Some(owner2.clone())); + } + mod reply_data_overwrite { use super::*; From a691beb8861e1769fe1d26a44cc6fc716cd478c9 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 28 Sep 2022 14:44:03 +0200 Subject: [PATCH 486/631] Remove unnecessary clones --- packages/multi-test/src/app.rs | 2 +- packages/multi-test/src/wasm.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index f526712f1..8227bff24 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -1887,7 +1887,7 @@ mod test { // check admin still the same let info = app.contract_data(&contract).unwrap(); - assert_eq!(info.admin, Some(owner2.clone())); + assert_eq!(info.admin, Some(owner2)); } mod reply_data_overwrite { diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index a6ec76bb8..7a34c21f3 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -1484,7 +1484,7 @@ mod test { &mut wasm_storage, &mock_router(), &block, - admin.clone(), + admin, WasmMsg::UpdateAdmin { contract_addr: contract_addr.to_string(), admin: new_admin.to_string(), From 86bd5692e43e45b8be45077d5793d2cc7f578356 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 28 Sep 2022 15:37:24 +0200 Subject: [PATCH 487/631] Fix error message Co-authored-by: Tomasz Kurcz --- packages/multi-test/src/wasm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 7a34c21f3..54afe9681 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -342,7 +342,7 @@ where // check admin status let mut data = self.load_contract(storage, &contract_addr)?; if data.admin != Some(sender) { - bail!("Only admin can clear contract admin: {:?}", data.admin); + bail!("Only admin can update the contract admin: {:?}", data.admin); } // update admin field data.admin = admin; From 263ff5c2a021dc0a9e76fb871b2d521d4451af1b Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 11:39:13 +0200 Subject: [PATCH 488/631] Remove storage-plus dependency from storage-macro --- Cargo.lock | 1 - packages/storage-macro/Cargo.toml | 1 - packages/{storage-macro => storage-plus}/tests/index_list.rs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) rename packages/{storage-macro => storage-plus}/tests/index_list.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index 93c0d63f0..0f790ab7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,7 +433,6 @@ name = "cw-storage-macro" version = "0.15.1" dependencies = [ "cosmwasm-std", - "cw-storage-plus", "serde", "syn", ] diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index 48cd9537d..ce5740516 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -16,6 +16,5 @@ proc-macro = true syn = { version = "1.0.96", features = ["full"] } [dev-dependencies] -cw-storage-plus = { version = "<=0.15.1, >=0.14.0", path = "../storage-plus" } cosmwasm-std = { version = "1.1.0", default-features = false } serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-macro/tests/index_list.rs b/packages/storage-plus/tests/index_list.rs similarity index 97% rename from packages/storage-macro/tests/index_list.rs rename to packages/storage-plus/tests/index_list.rs index 224b20551..db0d2b843 100644 --- a/packages/storage-macro/tests/index_list.rs +++ b/packages/storage-plus/tests/index_list.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test, feature = "iterator", feature = "macro"))] mod test { use cosmwasm_std::{testing::MockStorage, Addr}; use cw_storage_macro::index_list; From 7cf390fdc3cc17be1db0c67b060aafbfba3567fe Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 11:39:35 +0200 Subject: [PATCH 489/631] Add docs to storage-macro index_list --- packages/storage-macro/src/lib.rs | 19 +++++++++++++++++++ packages/storage-plus/src/lib.rs | 1 - 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/storage-macro/src/lib.rs b/packages/storage-macro/src/lib.rs index 366723ca5..21f19d91d 100644 --- a/packages/storage-macro/src/lib.rs +++ b/packages/storage-macro/src/lib.rs @@ -5,6 +5,25 @@ use syn::{ parse_macro_input, ItemStruct, }; +/// Auto generate an `IndexList` impl for your indexes struct. +/// +/// # Example +/// +/// ```rust +/// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +/// struct TestStruct { +/// id: u64, +/// id2: u32, +/// addr: Addr, +/// } +/// +/// #[index_list(TestStruct)] // <- Add this line right here. +/// struct TestIndexes<'a> { +/// id: MultiIndex<'a, u32, TestStruct, u64>, +/// addr: UniqueIndex<'a, Addr, TestStruct>, +/// } +/// ``` +/// #[proc_macro_attribute] pub fn index_list(attr: TokenStream, item: TokenStream) -> TokenStream { let input = parse_macro_input!(item as ItemStruct); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 014834bf8..79266d3b5 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -46,5 +46,4 @@ pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; #[macro_use] extern crate cw_storage_macro; #[cfg(all(feature = "iterator", feature = "macro"))] -#[doc(hidden)] pub use cw_storage_macro::*; From dfa8998d4eb8c7141496044a35f0df3493c252bf Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 11:40:36 +0200 Subject: [PATCH 490/631] Run storage-plus macro tests in CI --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 75ba021d7..4602c28b6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -660,11 +660,11 @@ jobs: name: Run unit tests (no iterator) command: cargo test --locked --no-default-features - run: - name: Build library for native target (with iterator) - command: cargo build --locked + name: Build library for native target (with iterator and macro) + command: cargo build --locked --all-features - run: - name: Run unit tests (with iterator) - command: cargo test --locked + name: Run unit tests (with iterator and macro) + command: cargo test --locked --all-features - save_cache: paths: - /usr/local/cargo/registry From ce2300f1ccb83bcacef2cd36ddc16843353aa8cc Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 12:44:57 +0200 Subject: [PATCH 491/631] Enable all storage-plus features on docs.rs build --- packages/storage-plus/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index 7f453420a..b170ff34b 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -8,6 +8,9 @@ license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" +[package.metadata.docs.rs] +all-features = true # include macro feature when building docs + [features] default = ["iterator"] iterator = ["cosmwasm-std/iterator"] @@ -24,7 +27,7 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } cw-storage-macro = { version = "0.15.1", optional = true, path = "../storage-macro" } [dev-dependencies] -criterion = { version = "0.3", features = [ "html_reports" ] } +criterion = { version = "0.3", features = ["html_reports"] } rand = "0.8" [[bench]] From 292458d53154eff68c5351a8529e8af03bfe2525 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 13:07:09 +0200 Subject: [PATCH 492/631] Move index_list macro docs to storage-plus --- packages/storage-macro/src/lib.rs | 19 ------------------- packages/storage-plus/src/lib.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/storage-macro/src/lib.rs b/packages/storage-macro/src/lib.rs index 21f19d91d..366723ca5 100644 --- a/packages/storage-macro/src/lib.rs +++ b/packages/storage-macro/src/lib.rs @@ -5,25 +5,6 @@ use syn::{ parse_macro_input, ItemStruct, }; -/// Auto generate an `IndexList` impl for your indexes struct. -/// -/// # Example -/// -/// ```rust -/// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -/// struct TestStruct { -/// id: u64, -/// id2: u32, -/// addr: Addr, -/// } -/// -/// #[index_list(TestStruct)] // <- Add this line right here. -/// struct TestIndexes<'a> { -/// id: MultiIndex<'a, u32, TestStruct, u64>, -/// addr: UniqueIndex<'a, Addr, TestStruct>, -/// } -/// ``` -/// #[proc_macro_attribute] pub fn index_list(attr: TokenStream, item: TokenStream) -> TokenStream { let input = parse_macro_input!(item as ItemStruct); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 79266d3b5..f5484a993 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -42,8 +42,34 @@ pub use prefix::{range_with_prefix, Prefix}; #[cfg(feature = "iterator")] pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; +// cw_storage_macro reexports #[cfg(all(feature = "iterator", feature = "macro"))] #[macro_use] extern crate cw_storage_macro; #[cfg(all(feature = "iterator", feature = "macro"))] +/// Auto generate an `IndexList` impl for your indexes struct. +/// +/// # Example +/// +/// ```rust +/// use cosmwasm_std::Addr; +/// use cw_storage_plus::{MultiIndex, UniqueIndex, index_list}; +/// use serde::{Serialize, Deserialize}; +/// +/// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +/// struct TestStruct { +/// id: u64, +/// id2: u32, +/// addr: Addr, +/// } +/// +/// #[index_list(TestStruct)] // <- Add this line right here. +/// struct TestIndexes<'a> { +/// id: MultiIndex<'a, u32, TestStruct, u64>, +/// addr: UniqueIndex<'a, Addr, TestStruct>, +/// } +/// ``` +/// +pub use cw_storage_macro::index_list; +#[cfg(all(feature = "iterator", feature = "macro"))] pub use cw_storage_macro::*; From d037bf550f6718cc5c17fb3a1b25211d37d787c1 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 13:33:24 +0200 Subject: [PATCH 493/631] Remove blanket export --- packages/storage-plus/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index f5484a993..00208b499 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -71,5 +71,3 @@ extern crate cw_storage_macro; /// ``` /// pub use cw_storage_macro::index_list; -#[cfg(all(feature = "iterator", feature = "macro"))] -pub use cw_storage_macro::*; From 0af81440b4de0f4868e7c33f27be428e0b85af4e Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 14:58:32 +0200 Subject: [PATCH 494/631] Add cw1155-base readme --- contracts/cw1155-base/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 contracts/cw1155-base/README.md diff --git a/contracts/cw1155-base/README.md b/contracts/cw1155-base/README.md new file mode 100644 index 000000000..6da195595 --- /dev/null +++ b/contracts/cw1155-base/README.md @@ -0,0 +1,24 @@ +# CW1155 Basic + +This is a basic implementation of a cw1155 contract. +It implements the [CW1155 spec](../../packages/cw1155/README.md) and manages multiple tokens +(fungible or non-fungible) under one contract. + +## Instantiation + +To create it, you must pass in a `minter` address. + +```rust +#[cw_serde] +pub struct InstantiateMsg { + /// The minter is the only one who can create new tokens. + /// This is designed for a base token platform that is controlled by an external program or + /// contract. + pub minter: String, +} +``` + +## Messages + +All other messages and queries are defined by the +[CW1155 spec](../../packages/cw1155/README.md). Please refer to it for more info. \ No newline at end of file From a2cc67e7acd5ae5a7ba70b44ab288463fff823d0 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 15:59:06 +0200 Subject: [PATCH 495/631] Add contract crate docs based on readme --- contracts/cw1-subkeys/src/lib.rs | 13 ++++++++++++ contracts/cw1-whitelist-ng/src/lib.rs | 20 ++++++++++++++++++ contracts/cw1-whitelist/src/lib.rs | 20 ++++++++++++++++++ contracts/cw1155-base/src/lib.rs | 9 +++++++++ contracts/cw20-base/src/lib.rs | 16 +++++++++++++++ contracts/cw20-ics20/src/lib.rs | 13 ++++++++++++ contracts/cw3-fixed-multisig/src/lib.rs | 18 +++++++++++++++++ contracts/cw3-flex-multisig/src/lib.rs | 24 ++++++++++++++++++++++ contracts/cw4-group/src/lib.rs | 16 +++++++++++++++ contracts/cw4-stake/src/lib.rs | 27 +++++++++++++++++++++++++ 10 files changed, 176 insertions(+) diff --git a/contracts/cw1-subkeys/src/lib.rs b/contracts/cw1-subkeys/src/lib.rs index dfedc9dc6..1c0c7c6a4 100644 --- a/contracts/cw1-subkeys/src/lib.rs +++ b/contracts/cw1-subkeys/src/lib.rs @@ -1,3 +1,16 @@ +/*! +This builds on [`cw1_whitelist`] to provide the first non-trivial solution. +It still works like [`cw1_whitelist`] with a set of admins (typically 1) +which have full control of the account. However, you can then grant +a number of accounts allowances to send native tokens from this account. + +This was proposed in Summer 2019 for the Cosmos Hub and resembles the +functionality of ERC20 (allowances and transfer from). + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1-subkeys/README.md). +*/ + pub mod contract; mod error; pub mod msg; diff --git a/contracts/cw1-whitelist-ng/src/lib.rs b/contracts/cw1-whitelist-ng/src/lib.rs index bdb81526c..e2bbe8650 100644 --- a/contracts/cw1-whitelist-ng/src/lib.rs +++ b/contracts/cw1-whitelist-ng/src/lib.rs @@ -1,3 +1,23 @@ +/*! +This may be the simplest implementation of [CW1](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1/README.md), a whitelist of addresses. +It contains a set of admins that are defined upon creation. +Any of those admins may `Execute` any message via the contract, +per the CW1 spec. + +To make this slighly less minimalistic, you can allow the admin set +to be mutable or immutable. If it is mutable, then any admin may +(a) change the admin set and (b) freeze it (making it immutable). + +While largely an example contract for CW1, this has various real-world use-cases, +such as a common account that is shared among multiple trusted devices, +or trading an entire account (used as 1 of 1 mutable). Most of the time, +this can be used as a framework to build your own, +more advanced cw1 implementations. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1-whitelist-ng/README.md). +*/ + mod contract; pub mod error; pub mod interfaces; diff --git a/contracts/cw1-whitelist/src/lib.rs b/contracts/cw1-whitelist/src/lib.rs index 83686a729..a78fdf9bf 100644 --- a/contracts/cw1-whitelist/src/lib.rs +++ b/contracts/cw1-whitelist/src/lib.rs @@ -1,3 +1,23 @@ +/*! +This may be the simplest implementation of [CW1](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1/README.md), a whitelist of addresses. +It contains a set of admins that are defined upon creation. +Any of those admins may `Execute` any message via the contract, +per the CW1 spec. + +To make this slighly less minimalistic, you can allow the admin set +to be mutable or immutable. If it is mutable, then any admin may +(a) change the admin set and (b) freeze it (making it immutable). + +While largely an example contract for CW1, this has various real-world use-cases, +such as a common account that is shared among multiple trusted devices, +or trading an entire account (used as 1 of 1 mutable). Most of the time, +this can be used as a framework to build your own, +more advanced cw1 implementations. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1-whitelist/README.md). +*/ + pub mod contract; pub mod error; #[cfg(test)] diff --git a/contracts/cw1155-base/src/lib.rs b/contracts/cw1155-base/src/lib.rs index 0aa98a4f1..809e67e24 100644 --- a/contracts/cw1155-base/src/lib.rs +++ b/contracts/cw1155-base/src/lib.rs @@ -1,3 +1,12 @@ +/*! +This is a basic implementation of a cw1155 contract. +It implements the [CW1155 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1155/README.md) and manages multiple tokens +(fungible or non-fungible) under one contract. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1155-base/README.md). +*/ + pub mod contract; mod error; pub mod execute; diff --git a/contracts/cw20-base/src/lib.rs b/contracts/cw20-base/src/lib.rs index 64e8019b6..7b601f25d 100644 --- a/contracts/cw20-base/src/lib.rs +++ b/contracts/cw20-base/src/lib.rs @@ -1,3 +1,19 @@ +/*! +This is a basic implementation of a cw20 contract. It implements +the [CW20 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw20/README.md) and is designed to +be deployed as is, or imported into other contracts to easily build +cw20-compatible tokens with custom logic. + +Implements: + +- [x] CW20 Base +- [x] Mintable extension +- [x] Allowances extension + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/README.md). +*/ + pub mod allowances; pub mod contract; pub mod enumerable; diff --git a/contracts/cw20-ics20/src/lib.rs b/contracts/cw20-ics20/src/lib.rs index b9ceef245..6260eef54 100644 --- a/contracts/cw20-ics20/src/lib.rs +++ b/contracts/cw20-ics20/src/lib.rs @@ -1,3 +1,16 @@ +/*! +This is an *IBC Enabled* contract that allows us to send CW20 tokens from one chain over the standard ICS20 +protocol to the bank module of another chain. In short, it let's us send our custom CW20 tokens with IBC and use +them just like native tokens on other chains. + +It is only designed to send tokens and redeem previously sent tokens. It will not mint tokens belonging +to assets originating on the foreign chain. This is different than the Golang `ibctransfer` module, but +we properly implement ICS20 and respond with an error message... let's hope the Go side handles this correctly. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-ics20/README.md). +*/ + pub mod amount; pub mod contract; mod error; diff --git a/contracts/cw3-fixed-multisig/src/lib.rs b/contracts/cw3-fixed-multisig/src/lib.rs index a1d10d0d5..9053ec94d 100644 --- a/contracts/cw3-fixed-multisig/src/lib.rs +++ b/contracts/cw3-fixed-multisig/src/lib.rs @@ -1,3 +1,21 @@ +/*! +This is a simple implementation of the [cw3 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). +It is a multisig with a fixed set of addresses created upon instatiation. +Each address may have the same weight (K of N), or some may have extra voting +power. This works much like the native Cosmos SDK multisig, except that rather +than aggregating the signatures off chain and submitting the final result, +we aggregate the approvals on-chain. + +This is usable as is, and probably the most secure implementation of cw3 +(as it is the simplest), but we will be adding more complex cases, such +as updating the multisig set, different voting rules for the same group +with different permissions, and even allow token-weighted voting. All through +the same client interface. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-fixed-multisig/README.md). +*/ + pub mod contract; mod error; mod integration_tests; diff --git a/contracts/cw3-flex-multisig/src/lib.rs b/contracts/cw3-flex-multisig/src/lib.rs index e5ff7237e..cdd95d2dd 100644 --- a/contracts/cw3-flex-multisig/src/lib.rs +++ b/contracts/cw3-flex-multisig/src/lib.rs @@ -1,3 +1,27 @@ +/*! +This builds on [`cw3_fixed_multisig`] with a more +powerful implementation of the [cw3 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). +It is a multisig contract that is backed by a +[cw4 (group)](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md) contract, which independently +maintains the voter set. + +This provides 2 main advantages: + +* You can create two different multisigs with different voting thresholds + backed by the same group. Thus, you can have a 50% vote, and a 67% vote + that always use the same voter set, but can take other actions. +* TODO: It allows dynamic multisig groups. + + +In addition to the dynamic voting set, the main difference with the native +Cosmos SDK multisig, is that it aggregates the signatures on chain, with +visible proposals (like `x/gov` in the Cosmos SDK), rather than requiring +signers to share signatures off chain. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-flex-multisig/README.md). +*/ + pub mod contract; pub mod error; pub mod msg; diff --git a/contracts/cw4-group/src/lib.rs b/contracts/cw4-group/src/lib.rs index 99fcca8b4..779325274 100644 --- a/contracts/cw4-group/src/lib.rs +++ b/contracts/cw4-group/src/lib.rs @@ -1,3 +1,19 @@ +/*! +This is a basic implementation of the [cw4 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). +It fulfills all elements of the spec, including the raw query lookups, +and it designed to be used as a backing storage for +[cw3 compliant contracts](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). + +It stores a set of members along with an admin, and allows the admin to +update the state. Raw queries (intended for cross-contract queries) +can check a given member address and the total weight. Smart queries (designed +for client API) can do the same, and also query the admin address as well as +paginate over all members. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw4-group/README.md). +*/ + pub mod contract; pub mod error; pub mod helpers; diff --git a/contracts/cw4-stake/src/lib.rs b/contracts/cw4-stake/src/lib.rs index dfedc9dc6..6ff3f6f15 100644 --- a/contracts/cw4-stake/src/lib.rs +++ b/contracts/cw4-stake/src/lib.rs @@ -1,3 +1,30 @@ +/*! +This is a second implementation of the [cw4 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). +It fulfills all elements of the spec, including the raw query lookups, +and is designed to be used as a backing storage for +[cw3 compliant contracts](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). + +It provides a similar API to [`cw4-group`](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw4-group/README.md) +(which handles elected membership), +but rather than appointing members (by admin or multisig), their +membership and weight are based on the number of tokens they have staked. +This is similar to many DAOs. + +Only one denom can be bonded with both `min_bond` as the minimum amount +that must be sent by one address to enter, as well as `tokens_per_weight`, +which can be used to normalize the weight (eg. if the token is uatom +and you want 1 weight per ATOM, you can set `tokens_per_weight = 1_000_000`). + +There is also an unbonding period (`Duration`) which sets how long the +tokens are frozen before being released. These frozen tokens can neither +be used for voting, nor claimed by the original owner. Only after the period +can you get your tokens back. This liquidity loss is the "skin in the game" +provided by staking to this contract. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw4-stake/README.md). +*/ + pub mod contract; mod error; pub mod msg; From 42bec3cb136397c454e312965b5d993502192951 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 29 Sep 2022 16:26:05 +0200 Subject: [PATCH 496/631] Add package crate docs based on readme --- packages/controllers/src/lib.rs | 16 ++++++++++++++++ packages/cw1/src/lib.rs | 23 +++++++++++++++++++++++ packages/cw1155/src/lib.rs | 16 ++++++++++++++++ packages/cw2/src/lib.rs | 19 +++++++++++++++++++ packages/cw20/README.md | 2 +- packages/cw20/src/lib.rs | 11 +++++++++++ packages/cw3/src/lib.rs | 11 +++++++++++ packages/cw4/src/lib.rs | 21 +++++++++++++++++++++ packages/storage-macro/src/lib.rs | 7 +++++++ packages/storage-plus/src/lib.rs | 15 +++++++++++++++ packages/utils/src/lib.rs | 8 ++++++++ 11 files changed, 148 insertions(+), 1 deletion(-) diff --git a/packages/controllers/src/lib.rs b/packages/controllers/src/lib.rs index eb767b74f..4d17478d6 100644 --- a/packages/controllers/src/lib.rs +++ b/packages/controllers/src/lib.rs @@ -1,3 +1,19 @@ +/*! +This is a collection of "controllers" that we end up reimplementing in +many contracts. I use the word "controller" similar to the MVC framework +style, where it is an element that encapsulated business logic and data access. +We can also directly handle some `ExecuteMsg` and `QueryMsg` variants by +adding a sub-router to these controllers. + +This is the beginning of an experiment in code composition, and how best to +reuse code among multiple contracts. We have already seen some "extend" and +existing base contract (like `cw20-staking` extends `cw20-base`), but this +goes for smaller scale units. + +Supported controllers: + +* Admin (`UpdateAdmin` handler, `Admin` querier, set_admin and is_admin methods) +*/ mod admin; mod claim; mod hooks; diff --git a/packages/cw1/src/lib.rs b/packages/cw1/src/lib.rs index a21f8502e..b5a8571f6 100644 --- a/packages/cw1/src/lib.rs +++ b/packages/cw1/src/lib.rs @@ -1,3 +1,26 @@ +/*! +CW1 is a specification for proxy contracts based on CosmWasm. +It is a very simple, but flexible interface designed for the case +where one contract is meant to hold assets (or rights) on behalf of +other contracts. + +The simplest example is a contract that will accept messages from +the creator and resend them from it's address. Simply by making this +transferable, you can then begin to transfer non-transferable assets +(eg. staked tokens, voting power, etc). + +You can imagine more complex examples, such as a "1 of N" multisig, +or conditional approval, where "sub-accounts" have the right to spend +a limited amount of funds from this account, with a "admin account" +retaining full control. + +The common denominator is that they allow you to immediately +execute arbitrary `CosmosMsg` in the same transaction. + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1/README.md). +*/ + pub mod helpers; pub mod msg; pub mod query; diff --git a/packages/cw1155/src/lib.rs b/packages/cw1155/src/lib.rs index dfea27c4f..69bfc5f77 100644 --- a/packages/cw1155/src/lib.rs +++ b/packages/cw1155/src/lib.rs @@ -1,3 +1,19 @@ +/*! +CW1155 is a specification for managing multiple tokens based on CosmWasm. +The name and design is based on Ethereum's ERC1155 standard. + +The specification is split into multiple sections, a contract may only +implement some of this functionality, but must implement the base. + +Fungible tokens and non-fungible tokens are treated equally, non-fungible tokens just have one max supply. + +Approval is set or unset to some operator over entire set of tokens. (More nuanced control is defined in +[ERC1761](https://eips.ethereum.org/EIPS/eip-1761)) + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1155/README.md). +*/ + pub use cw_utils::Expiration; pub use crate::event::{ApproveAllEvent, MetadataEvent, TransferEvent}; diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index f6c55ff79..4866d54b1 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -1,3 +1,22 @@ +/*! +Most of the CW* specs are focused on the *public interfaces* +of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. +However, when we wish to migrate or inspect smart contract info, +we need some form of smart contract information embedded on state. + +This is where CW2 comes in. It specifies on special Item to +be stored on disk by all contracts on `instantiate`. + +`ContractInfo` is must be stored under `"contract_info"` key which translates +to `"636F6E74726163745F696E666F"` in hex format. +Since the state is well defined, we do not need to support any "smart queries". +We do provide a helper to construct a "raw query" to read the ContractInfo +of any CW2-compliant contract. + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw2/README.md). +*/ + use cosmwasm_schema::cw_serde; use cosmwasm_std::{Empty, Querier, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery}; use cw_storage_plus::Item; diff --git a/packages/cw20/README.md b/packages/cw20/README.md index f4705625b..c09cec75b 100644 --- a/packages/cw20/README.md +++ b/packages/cw20/README.md @@ -3,7 +3,7 @@ CW20 is a specification for fungible tokens based on CosmWasm. The name and design is loosely based on Ethereum's ERC20 standard, but many changes have been made. The types in here can be imported by -contracts that wish to implement this spec, or by contracts that call +contracts that wish to implement this spec, or by contracts that call to any standard cw20 contract. The specification is split into multiple sections, a contract may only diff --git a/packages/cw20/src/lib.rs b/packages/cw20/src/lib.rs index 034d5de72..f99ea08a3 100644 --- a/packages/cw20/src/lib.rs +++ b/packages/cw20/src/lib.rs @@ -1,3 +1,14 @@ +/*! +CW20 is a specification for fungible tokens based on CosmWasm. +The name and design is loosely based on Ethereum's ERC20 standard, +but many changes have been made. The types in here can be imported by +contracts that wish to implement this spec, or by contracts that call +to any standard cw20 contract. + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw20/README.md). +*/ + pub use cw_utils::Expiration; pub use crate::balance::Balance; diff --git a/packages/cw3/src/lib.rs b/packages/cw3/src/lib.rs index bda9d2d93..0740a8e44 100644 --- a/packages/cw3/src/lib.rs +++ b/packages/cw3/src/lib.rs @@ -1,3 +1,14 @@ +/*! +CW3 is a specification for voting contracts based on CosmWasm. +It is an extension of CW1 (which served as an immediate 1 of N multisig). +In this case, no key can immediately execute, but only propose +a set of messages for execution. The proposal, subsequent +approvals, and signature aggregation all happen on chain. + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). +*/ + // mod helpers; mod helpers; mod msg; diff --git a/packages/cw4/src/lib.rs b/packages/cw4/src/lib.rs index f57fd27d8..9aa21c717 100644 --- a/packages/cw4/src/lib.rs +++ b/packages/cw4/src/lib.rs @@ -1,3 +1,24 @@ +/*! +CW4 is a spec for storing group membership, which can be combined +with CW3 multisigs. The purpose is to store a set of members/voters +that can be accessed to determine permissions in another section. + +Since this is often deployed as a contract pair, we expect this +contract to often be queried with `QueryRaw` and the internal +layout of some of the data structures becomes part of the public API. +Implementations may add more data structures, but at least +the ones laid out here should be under the specified keys and in the +same format. + +In this case, a cw3 contract could *read* an external group contract with +no significant cost more than reading local storage. However, updating +that group contract (if allowed), would be an external message and +charged the instantiation overhead for each contract. + +For more information on this specification, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). +*/ + mod helpers; mod hook; mod msg; diff --git a/packages/storage-macro/src/lib.rs b/packages/storage-macro/src/lib.rs index 366723ca5..23ecc5c5f 100644 --- a/packages/storage-macro/src/lib.rs +++ b/packages/storage-macro/src/lib.rs @@ -1,3 +1,10 @@ +/*! +Procedural macros helper for interacting with cw-storage-plus and cosmwasm-storage. + +For more information on this package, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/storage-macro/README.md). +*/ + use proc_macro::TokenStream; use syn::{ Ident, diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 00208b499..804b2db95 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -1,3 +1,18 @@ +/*! +After building `cosmwasm-storage`, we realized many of the design decisions were +limiting us and producing a lot of needless boilerplate. The decision was made to leave +those APIs stable for anyone wanting a very basic abstraction on the KV-store and to +build a much more powerful and complex ORM layer that can provide powerful accessors +using complex key types, which are transparently turned into bytes. + +This led to a number of breaking API changes in this package of the course of several +releases as we updated this with lots of experience, user feedback, and deep dives to harness +the full power of generics. + +For more information on this package, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/storage-plus/README.md). +*/ + mod bound; mod de; mod deque; diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index cf60d22c7..d88e65921 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,3 +1,11 @@ +/*! +This is a collection of common types shared among many specs. +For example [`Expiration`], which is embedded in many places. + +Types should only be added here after they are duplicated in +a second contract, not "because we might need it" +*/ + mod balance; mod event; mod expiration; From 441474f40f2c6f26f48994a4122b4f131b93e91d Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 30 Sep 2022 15:38:28 +0200 Subject: [PATCH 497/631] Fix typos --- contracts/cw20-ics20/README.md | 2 +- contracts/cw20-ics20/src/lib.rs | 2 +- packages/cw1/README.md | 2 +- packages/cw1/src/lib.rs | 2 +- packages/cw2/README.md | 4 ++-- packages/cw2/src/lib.rs | 4 ++-- packages/cw4/README.md | 4 ++-- packages/cw4/src/lib.rs | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/cw20-ics20/README.md b/contracts/cw20-ics20/README.md index 3feae9a19..9be95ff95 100644 --- a/contracts/cw20-ics20/README.md +++ b/contracts/cw20-ics20/README.md @@ -1,7 +1,7 @@ # CW20 ICS20 This is an *IBC Enabled* contract that allows us to send CW20 tokens from one chain over the standard ICS20 -protocol to the bank module of another chain. In short, it let's us send our custom CW20 tokens with IBC and use +protocol to the bank module of another chain. In short, it lets us send our custom CW20 tokens with IBC and use them just like native tokens on other chains. It is only designed to send tokens and redeem previously sent tokens. It will not mint tokens belonging diff --git a/contracts/cw20-ics20/src/lib.rs b/contracts/cw20-ics20/src/lib.rs index 6260eef54..a9dba517d 100644 --- a/contracts/cw20-ics20/src/lib.rs +++ b/contracts/cw20-ics20/src/lib.rs @@ -1,6 +1,6 @@ /*! This is an *IBC Enabled* contract that allows us to send CW20 tokens from one chain over the standard ICS20 -protocol to the bank module of another chain. In short, it let's us send our custom CW20 tokens with IBC and use +protocol to the bank module of another chain. In short, it lets us send our custom CW20 tokens with IBC and use them just like native tokens on other chains. It is only designed to send tokens and redeem previously sent tokens. It will not mint tokens belonging diff --git a/packages/cw1/README.md b/packages/cw1/README.md index 78df4593c..72a95915a 100644 --- a/packages/cw1/README.md +++ b/packages/cw1/README.md @@ -6,7 +6,7 @@ where one contract is meant to hold assets (or rights) on behalf of other contracts. The simplest example is a contract that will accept messages from -the creator and resend them from it's address. Simply by making this +the creator and resend them from its address. Simply by making this transferable, you can then begin to transfer non-transferable assets (eg. staked tokens, voting power, etc). diff --git a/packages/cw1/src/lib.rs b/packages/cw1/src/lib.rs index b5a8571f6..a73529538 100644 --- a/packages/cw1/src/lib.rs +++ b/packages/cw1/src/lib.rs @@ -5,7 +5,7 @@ where one contract is meant to hold assets (or rights) on behalf of other contracts. The simplest example is a contract that will accept messages from -the creator and resend them from it's address. Simply by making this +the creator and resend them from its address. Simply by making this transferable, you can then begin to transfer non-transferable assets (eg. staked tokens, voting power, etc). diff --git a/packages/cw2/README.md b/packages/cw2/README.md index 3d1e31781..b80c599a2 100644 --- a/packages/cw2/README.md +++ b/packages/cw2/README.md @@ -5,10 +5,10 @@ of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. However, when we wish to migrate or inspect smart contract info, we need some form of smart contract information embedded on state. -This is where CW2 comes in. It specifies on special Item to +This is where CW2 comes in. It specifies a special Item to be stored on disk by all contracts on `instantiate`. -`ContractInfo` is must be stored under `"contract_info"` key which translates +`ContractInfo` must be stored under the `"contract_info"` key which translates to `"636F6E74726163745F696E666F"` in hex format. Since the state is well defined, we do not need to support any "smart queries". We do provide a helper to construct a "raw query" to read the ContractInfo diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index 4866d54b1..12cb7b594 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -4,10 +4,10 @@ of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. However, when we wish to migrate or inspect smart contract info, we need some form of smart contract information embedded on state. -This is where CW2 comes in. It specifies on special Item to +This is where CW2 comes in. It specifies a special Item to be stored on disk by all contracts on `instantiate`. -`ContractInfo` is must be stored under `"contract_info"` key which translates +`ContractInfo` must be stored under the `"contract_info"` key which translates to `"636F6E74726163745F696E666F"` in hex format. Since the state is well defined, we do not need to support any "smart queries". We do provide a helper to construct a "raw query" to read the ContractInfo diff --git a/packages/cw4/README.md b/packages/cw4/README.md index 3cf96ae9e..d2203088d 100644 --- a/packages/cw4/README.md +++ b/packages/cw4/README.md @@ -12,9 +12,9 @@ the ones laid out here should be under the specified keys and in the same format. In this case, a cw3 contract could *read* an external group contract with -no significant cost more than reading local storage. However, updating +no significant cost besides reading local storage. However, updating that group contract (if allowed), would be an external message and -charged the instantiation overhead for each contract. +will be charged as part of the overhead for each contract. ## Messages diff --git a/packages/cw4/src/lib.rs b/packages/cw4/src/lib.rs index 9aa21c717..71c6f2e0d 100644 --- a/packages/cw4/src/lib.rs +++ b/packages/cw4/src/lib.rs @@ -11,9 +11,9 @@ the ones laid out here should be under the specified keys and in the same format. In this case, a cw3 contract could *read* an external group contract with -no significant cost more than reading local storage. However, updating +no significant cost besides reading local storage. However, updating that group contract (if allowed), would be an external message and -charged the instantiation overhead for each contract. +will be charged as part of the overhead for each contract. For more information on this specification, please check out the [README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). From 824ccd60b85cd1219707a7792902af80ebe47a50 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 4 Oct 2022 10:00:07 +0200 Subject: [PATCH 498/631] Remove iterator feature check for deque --- packages/storage-plus/src/deque.rs | 9 --------- packages/storage-plus/src/lib.rs | 1 - 2 files changed, 10 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 6c51440cb..9e0a4a1d6 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -196,7 +196,6 @@ fn calc_len(head: u32, tail: u32) -> u32 { tail.wrapping_sub(head) } -#[cfg(feature = "iterator")] impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { Ok(VecDequeIter { @@ -208,7 +207,6 @@ impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { } } -#[cfg(feature = "iterator")] pub struct VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, @@ -219,7 +217,6 @@ where end: u32, } -#[cfg(feature = "iterator")] impl<'a, T> Iterator for VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, @@ -261,7 +258,6 @@ where } } -#[cfg(feature = "iterator")] impl<'a, T> DoubleEndedIterator for VecDequeIter<'a, T> where T: Serialize + DeserializeOwned, @@ -375,7 +371,6 @@ mod tests { } #[test] - #[cfg(feature = "iterator")] fn iterator() { let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); @@ -401,7 +396,6 @@ mod tests { } #[test] - #[cfg(feature = "iterator")] fn reverse_iterator() { let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); @@ -463,7 +457,6 @@ mod tests { } #[test] - #[cfg(feature = "iterator")] fn wrapping_iterator() { let deque: VecDeque = VecDeque::new("test"); let mut store = MockStorage::new(); @@ -512,7 +505,6 @@ mod tests { const DATA: VecDeque = VecDeque::new("data"); #[test] - #[cfg(feature = "iterator")] fn readme_works() -> StdResult<()> { let mut store = MockStorage::new(); @@ -564,7 +556,6 @@ mod tests { } #[test] - #[cfg(feature = "iterator")] fn iterator_errors_when_item_missing() { let mut store = MockStorage::new(); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index 804b2db95..fe647eb70 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -34,7 +34,6 @@ mod snapshot; pub use bound::{Bound, Bounder, PrefixBound, RawBound}; pub use de::KeyDeserialize; pub use deque::VecDeque; -#[cfg(feature = "iterator")] pub use deque::VecDequeIter; pub use endian::Endian; #[cfg(feature = "iterator")] From 61faf19ead4914b36b8defbb3729f3efcb0fc5ea Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 4 Oct 2022 10:16:36 +0200 Subject: [PATCH 499/631] Rename Deque --- packages/storage-plus/src/deque.rs | 44 +++++++++++++++--------------- packages/storage-plus/src/lib.rs | 4 +-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs index 9e0a4a1d6..01932a5ea 100644 --- a/packages/storage-plus/src/deque.rs +++ b/packages/storage-plus/src/deque.rs @@ -14,14 +14,14 @@ const HEAD_KEY: &[u8] = b"h"; /// /// It has a maximum capacity of `u32::MAX - 1`. Make sure to never exceed that number when using this type. /// If you do, the methods won't work as intended anymore. -pub struct VecDeque<'a, T> { +pub struct Deque<'a, T> { // prefix of the deque items namespace: &'a [u8], // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed item_type: PhantomData, } -impl<'a, T> VecDeque<'a, T> { +impl<'a, T> Deque<'a, T> { pub const fn new(prefix: &'a str) -> Self { Self { namespace: prefix.as_bytes(), @@ -30,7 +30,7 @@ impl<'a, T> VecDeque<'a, T> { } } -impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { +impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { /// Adds the given value to the end of the deque pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { // save value @@ -196,9 +196,9 @@ fn calc_len(head: u32, tail: u32) -> u32 { tail.wrapping_sub(head) } -impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { - pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { - Ok(VecDequeIter { +impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { + pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { + Ok(DequeIter { deque: self, storage, start: self.head(storage)?, @@ -207,17 +207,17 @@ impl<'a, T: Serialize + DeserializeOwned> VecDeque<'a, T> { } } -pub struct VecDequeIter<'a, T> +pub struct DequeIter<'a, T> where T: Serialize + DeserializeOwned, { - deque: &'a VecDeque<'a, T>, + deque: &'a Deque<'a, T>, storage: &'a dyn Storage, start: u32, end: u32, } -impl<'a, T> Iterator for VecDequeIter<'a, T> +impl<'a, T> Iterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -258,7 +258,7 @@ where } } -impl<'a, T> DoubleEndedIterator for VecDequeIter<'a, T> +impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> where T: Serialize + DeserializeOwned, { @@ -290,7 +290,7 @@ where } #[cfg(test)] mod tests { - use crate::deque::VecDeque; + use crate::deque::Deque; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{StdError, StdResult}; @@ -298,7 +298,7 @@ mod tests { #[test] fn push_and_pop() { - const PEOPLE: VecDeque = VecDeque::new("people"); + const PEOPLE: Deque = Deque::new("people"); let mut store = MockStorage::new(); // push some entries @@ -334,7 +334,7 @@ mod tests { #[test] fn length() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); assert_eq!(deque.len(&store).unwrap(), 0); @@ -372,7 +372,7 @@ mod tests { #[test] fn iterator() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items @@ -397,7 +397,7 @@ mod tests { #[test] fn reverse_iterator() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); // push some items @@ -431,7 +431,7 @@ mod tests { #[test] fn wrapping() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); // simulate deque that was pushed and popped `u32::MAX` times @@ -458,7 +458,7 @@ mod tests { #[test] fn wrapping_iterator() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); deque.set_head(&mut store, u32::MAX); @@ -481,7 +481,7 @@ mod tests { #[test] fn front_back() { - let deque: VecDeque = VecDeque::new("test"); + let deque: Deque = Deque::new("test"); let mut store = MockStorage::new(); assert_eq!(deque.back(&store).unwrap(), None); @@ -502,7 +502,7 @@ mod tests { pub age: i32, } - const DATA: VecDeque = VecDeque::new("data"); + const DATA: Deque = Deque::new("data"); #[test] fn readme_works() -> StdResult<()> { @@ -559,7 +559,7 @@ mod tests { fn iterator_errors_when_item_missing() { let mut store = MockStorage::new(); - let deque = VecDeque::new("error_test"); + let deque = Deque::new("error_test"); deque.push_back(&mut store, &1u32).unwrap(); // manually remove it @@ -584,7 +584,7 @@ mod tests { fn get() { let mut store = MockStorage::new(); - let deque = VecDeque::new("test"); + let deque = Deque::new("test"); deque.push_back(&mut store, &1u32).unwrap(); deque.push_back(&mut store, &2).unwrap(); @@ -606,7 +606,7 @@ mod tests { ); // start fresh - let deque = VecDeque::new("test2"); + let deque = Deque::new("test2"); deque.push_back(&mut store, &0u32).unwrap(); deque.push_back(&mut store, &1).unwrap(); diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs index fe647eb70..a91f096a4 100644 --- a/packages/storage-plus/src/lib.rs +++ b/packages/storage-plus/src/lib.rs @@ -33,8 +33,8 @@ mod snapshot; #[cfg(feature = "iterator")] pub use bound::{Bound, Bounder, PrefixBound, RawBound}; pub use de::KeyDeserialize; -pub use deque::VecDeque; -pub use deque::VecDequeIter; +pub use deque::Deque; +pub use deque::DequeIter; pub use endian::Endian; #[cfg(feature = "iterator")] pub use indexed_map::{IndexList, IndexedMap}; From dc2b628fc5bd4a1953f4168baaab51e4c939b13e Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 11 Oct 2022 21:03:46 +0200 Subject: [PATCH 500/631] Remove cw1-whitelist-ng --- .circleci/config.yml | 29 -- Cargo.lock | 19 - contracts/cw1-whitelist-ng/.cargo/config | 6 - contracts/cw1-whitelist-ng/Cargo.toml | 41 -- contracts/cw1-whitelist-ng/NOTICE | 14 - contracts/cw1-whitelist-ng/README.md | 44 -- contracts/cw1-whitelist-ng/src/bin/schema.rs | 24 - contracts/cw1-whitelist-ng/src/contract.rs | 432 ------------------ contracts/cw1-whitelist-ng/src/error.rs | 11 - contracts/cw1-whitelist-ng/src/interfaces.rs | 44 -- contracts/cw1-whitelist-ng/src/lib.rs | 64 --- contracts/cw1-whitelist-ng/src/msg.rs | 149 ------ contracts/cw1-whitelist-ng/src/multitest.rs | 44 -- .../src/multitest/contract.rs | 239 ---------- contracts/cw1-whitelist-ng/src/query.rs | 57 --- contracts/cw1-whitelist-ng/src/state.rs | 91 ---- 16 files changed, 1308 deletions(-) delete mode 100644 contracts/cw1-whitelist-ng/.cargo/config delete mode 100644 contracts/cw1-whitelist-ng/Cargo.toml delete mode 100644 contracts/cw1-whitelist-ng/NOTICE delete mode 100644 contracts/cw1-whitelist-ng/README.md delete mode 100644 contracts/cw1-whitelist-ng/src/bin/schema.rs delete mode 100644 contracts/cw1-whitelist-ng/src/contract.rs delete mode 100644 contracts/cw1-whitelist-ng/src/error.rs delete mode 100644 contracts/cw1-whitelist-ng/src/interfaces.rs delete mode 100644 contracts/cw1-whitelist-ng/src/lib.rs delete mode 100644 contracts/cw1-whitelist-ng/src/msg.rs delete mode 100644 contracts/cw1-whitelist-ng/src/multitest.rs delete mode 100644 contracts/cw1-whitelist-ng/src/multitest/contract.rs delete mode 100644 contracts/cw1-whitelist-ng/src/query.rs delete mode 100644 contracts/cw1-whitelist-ng/src/state.rs diff --git a/.circleci/config.yml b/.circleci/config.yml index 4602c28b6..1bd7f83a6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,6 @@ workflows: jobs: - contract_cw1_subkeys - contract_cw1_whitelist - - contract_cw1_whitelist_ng - contract_cw3_fixed_multisig - contract_cw3_flex_multisig - contract_cw4_group @@ -109,33 +108,6 @@ jobs: - target key: cargocache-cw1-whitelist-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - contract_cw1_whitelist_ng: - docker: - - image: rust:1.58.1 - working_directory: ~/project/contracts/cw1-whitelist-ng - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw1-whitelist-ng-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw1-whitelist-ng-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - contract_cw3_fixed_multisig: docker: - image: rust:1.58.1 @@ -781,7 +753,6 @@ jobs: - run: name: Build and run schema generator for contracts command: | - export GLOBIGNORE='./contracts/cw1-whitelist-ng/' for C in ./contracts/*/ do echo "Generating schema for $C ..." diff --git a/Cargo.lock b/Cargo.lock index 0f790ab7c..a7074540d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -510,25 +510,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw1-whitelist-ng" -version = "0.15.1" -dependencies = [ - "anyhow", - "assert_matches", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw1", - "cw2", - "derivative", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "cw1155" version = "0.15.1" diff --git a/contracts/cw1-whitelist-ng/.cargo/config b/contracts/cw1-whitelist-ng/.cargo/config deleted file mode 100644 index f5174787c..000000000 --- a/contracts/cw1-whitelist-ng/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -wasm-debug = "build --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --bin schema" diff --git a/contracts/cw1-whitelist-ng/Cargo.toml b/contracts/cw1-whitelist-ng/Cargo.toml deleted file mode 100644 index d47fbb8cf..000000000 --- a/contracts/cw1-whitelist-ng/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "cw1-whitelist-ng" -version = "0.15.1" -authors = ["Bartłomiej Kuras "] -edition = "2018" -description = "Implementation of an proxy contract using a whitelist" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] -test-utils = [] -querier = ["library"] -# generate multitest interfaces -multitest = ["cw-multi-test", "anyhow"] - -[dependencies] -cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw1 = { path = "../../packages/cw1", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1", optional = true } -anyhow = { version = "1", optional = true } - -[dev-dependencies] -anyhow = "1" -assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } -derivative = "2" diff --git a/contracts/cw1-whitelist-ng/NOTICE b/contracts/cw1-whitelist-ng/NOTICE deleted file mode 100644 index 3002a4406..000000000 --- a/contracts/cw1-whitelist-ng/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW1-Whitelist: A minimal CosmWasm proxy contract -Copyright (C) 2020 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw1-whitelist-ng/README.md b/contracts/cw1-whitelist-ng/README.md deleted file mode 100644 index ca4f9597f..000000000 --- a/contracts/cw1-whitelist-ng/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# CW1 Whitelist - -This may be the simplest implementation of CW1, a whitelist of addresses. -It contains a set of admins that are defined upon creation. -Any of those admins may `Execute` any message via the contract, -per the CW1 spec. - -To make this slighly less minimalistic, you can allow the admin set -to be mutable or immutable. If it is mutable, then any admin may -(a) change the admin set and (b) freeze it (making it immutable). - -While largely an example contract for CW1, this has various real-world use-cases, -such as a common account that is shared among multiple trusted devices, -or trading an entire account (used as 1 of 1 mutable). Most of the time, -this can be used as a framework to build your own, -more advanced cw1 implementations. - -## Allowing Custom Messages - -By default, this doesn't support `CustomMsg` in order to be fully generic -among blockchains. However, all types are Generic over `T`, and this is only -fixed in `handle`. You can import this contract and just redefine your `handle` -function, setting a different parameter to `ExecuteMsg`, and you can produce -a chain-specific message. - -## Running this contract - -You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. - -You can run unit tests on this via: - -`cargo test` - -Once you are happy with the content, you can compile it to wasm via: - -``` -RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw1_whitelist.wasm . -ls -l cw1_whitelist.wasm -sha256sum cw1_whitelist.wasm -``` - -Or for a production-ready (optimized) build, run a build command in the -the repository root: https://github.com/CosmWasm/cw-plus#compiling. diff --git a/contracts/cw1-whitelist-ng/src/bin/schema.rs b/contracts/cw1-whitelist-ng/src/bin/schema.rs deleted file mode 100644 index 6e7b85ef2..000000000 --- a/contracts/cw1-whitelist-ng/src/bin/schema.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; - -use cw1_whitelist_ng::msg::*; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(Cw1ExecMsg), &out_dir, "Cw1ExecMsg"); - export_schema_with_title(&schema_for!(WhitelistExecMsg), &out_dir, "WhitelistExecMsg"); - export_schema_with_title(&schema_for!(Cw1QueryMsg), &out_dir, "Cw1QueryMsg"); - export_schema_with_title( - &schema_for!(WhitelistQueryMsg), - &out_dir, - "WhitelistQueryMsg", - ); - export_schema(&schema_for!(AdminListResponse), &out_dir); -} diff --git a/contracts/cw1-whitelist-ng/src/contract.rs b/contracts/cw1-whitelist-ng/src/contract.rs deleted file mode 100644 index 177b30034..000000000 --- a/contracts/cw1-whitelist-ng/src/contract.rs +++ /dev/null @@ -1,432 +0,0 @@ -use cosmwasm_std::{ - from_slice, Addr, Api, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdError, - StdResult, -}; -use serde::de::DeserializeOwned; - -use crate::error::ContractError; -use crate::interfaces::*; -use crate::msg::{ - AdminListResponse, Cw1ExecMsg, Cw1QueryMsg, InstantiateMsg, WhitelistExecMsg, WhitelistQueryMsg, -}; -use crate::state::{AdminList, Cw1WhitelistContract}; - -use cw1::CanExecuteResponse; -use cw2::set_contract_version; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw1-whitelist"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -pub fn validate_admins(api: &dyn Api, admins: &[String]) -> StdResult> { - admins.iter().map(|addr| api.addr_validate(addr)).collect() -} - -impl Cw1WhitelistContract { - pub fn instantiate( - &self, - deps: DepsMut, - _env: Env, - _info: MessageInfo, - admins: Vec, - mutable: bool, - ) -> Result, ContractError> { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let cfg = AdminList { - admins: validate_admins(deps.api, &admins)?, - mutable, - }; - - self.admin_list.save(deps.storage, &cfg)?; - Ok(Response::new()) - } - - pub fn is_admin(&self, deps: Deps, addr: &str) -> Result { - let cfg = self.admin_list.load(deps.storage)?; - Ok(cfg.is_admin(addr)) - } - - // Entry points, to be called only in actual entry points and by multitest `Contract` - // implementation - pub(crate) fn entry_instantiate( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: &[u8], - ) -> Result, ContractError> { - let msg: InstantiateMsg = from_slice(msg)?; - msg.dispatch(deps, env, info, self) - } - - pub(crate) fn entry_execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: &[u8], - ) -> Result, ContractError> - where - T: DeserializeOwned, - { - let cw1_err = match from_slice::>(msg) { - Ok(msg) => return msg.dispatch(deps, env, info, self), - Err(err) => err, - }; - - let whitelist_err = match from_slice::(msg) { - Ok(msg) => return msg.dispatch(deps, env, info, self), - Err(err) => err, - }; - - let msg = format!( - "While parsing Cw1WhitelistExecMsg\n As Cw1ExecMsg: {}\n As WhitelistExecMsg: {}", - cw1_err, whitelist_err - ); - - let err = StdError::parse_err("Cw1WhitelistExecMsg", msg); - Err(err.into()) - } - - pub(crate) fn entry_query( - &self, - deps: Deps, - env: Env, - msg: &[u8], - ) -> Result - where - T: DeserializeOwned, - { - let cw1_err = match from_slice::>(msg) { - Ok(msg) => return msg.dispatch(deps, env, self), - Err(err) => err, - }; - - let whitelist_err = match from_slice::(msg) { - Ok(msg) => return msg.dispatch(deps, env, self), - Err(err) => err, - }; - - let msg = format!( - "While parsing Cw1WhitelistQueryMsg\n As Cw1QueryMsg: {}\n As WhitelistQueryMsg: {}", - cw1_err, whitelist_err - ); - - let err = StdError::parse_err("Cw1WhitelistExecMsg", msg); - Err(err.into()) - } -} - -impl Cw1 for Cw1WhitelistContract { - type Error = ContractError; - - fn execute( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - msgs: Vec>, - ) -> Result, Self::Error> { - if !self.is_admin(deps.as_ref(), info.sender.as_ref())? { - Err(ContractError::Unauthorized {}) - } else { - let res = Response::new() - .add_messages(msgs) - .add_attribute("action", "execute"); - Ok(res) - } - } - - fn can_execute( - &self, - deps: Deps, - _env: Env, - sender: String, - _msg: CosmosMsg, - ) -> Result { - Ok(CanExecuteResponse { - can_execute: self.is_admin(deps, &sender)?, - }) - } -} - -impl Whitelist for Cw1WhitelistContract { - type Error = ContractError; - - fn freeze( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - ) -> Result, Self::Error> { - self.admin_list - .update(deps.storage, |mut cfg| -> Result<_, ContractError> { - if !cfg.can_modify(info.sender.as_str()) { - Err(ContractError::Unauthorized {}) - } else { - cfg.mutable = false; - Ok(cfg) - } - })?; - - Ok(Response::new().add_attribute("action", "freeze")) - } - - fn update_admins( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - admins: Vec, - ) -> Result, Self::Error> { - let api = deps.api; - self.admin_list - .update(deps.storage, |mut cfg| -> Result<_, ContractError> { - if !cfg.can_modify(info.sender.as_str()) { - Err(ContractError::Unauthorized {}) - } else { - cfg.admins = validate_admins(api, &admins)?; - Ok(cfg) - } - })?; - - Ok(Response::new().add_attribute("action", "update_admins")) - } - - fn admin_list(&self, deps: Deps, _env: Env) -> Result { - let cfg = self.admin_list.load(deps.storage)?; - Ok(AdminListResponse { - admins: cfg.admins.into_iter().map(|a| a.into()).collect(), - mutable: cfg.mutable, - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::msg::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coin, coins, to_binary, BankMsg, StakingMsg, SubMsg, WasmMsg}; - - #[test] - fn instantiate_and_modify_config() { - let contract = Cw1WhitelistContract::native(); - - let mut deps = mock_dependencies(); - - let alice = "alice"; - let bob = "bob"; - let carl = "carl"; - - let anyone = "anyone"; - - // instantiate the contract - let admins = vec![alice.to_owned(), bob.to_owned(), carl.to_owned()]; - let info = mock_info(anyone, &[]); - contract - .instantiate(deps.as_mut(), mock_env(), info, admins, true) - .unwrap(); - - // ensure expected config - let expected = AdminListResponse { - admins: vec![alice.to_string(), bob.to_string(), carl.to_string()], - mutable: true, - }; - assert_eq!( - contract.admin_list(deps.as_ref(), mock_env()).unwrap(), - expected - ); - - // anyone cannot modify the contract - let info = mock_info(anyone, &[]); - let err = contract - .update_admins(deps.as_mut(), mock_env(), info, vec![anyone.to_owned()]) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // but alice can kick out carl - let admins = vec![alice.to_owned(), bob.to_owned()]; - let info = mock_info(alice, &[]); - contract - .update_admins(deps.as_mut(), mock_env(), info, admins) - .unwrap(); - - // ensure expected config - let expected = AdminListResponse { - admins: vec![alice.to_string(), bob.to_string()], - mutable: true, - }; - assert_eq!( - contract.admin_list(deps.as_ref(), mock_env()).unwrap(), - expected - ); - - // carl cannot freeze it - let info = mock_info(carl, &[]); - let err = contract - .freeze(deps.as_mut(), mock_env(), info) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // but bob can - let info = mock_info(bob, &[]); - contract.freeze(deps.as_mut(), mock_env(), info).unwrap(); - let expected = AdminListResponse { - admins: vec![alice.to_owned(), bob.to_owned()], - mutable: false, - }; - assert_eq!( - contract.admin_list(deps.as_ref(), mock_env()).unwrap(), - expected - ); - - // and now alice cannot change it again - let info = mock_info(alice, &[]); - let err = contract - .update_admins(deps.as_mut(), mock_env(), info, vec![alice.to_owned()]) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - } - - #[test] - fn execute_messages_has_proper_permissions() { - let contract = Cw1WhitelistContract::native(); - let mut deps = mock_dependencies(); - - let alice = "alice"; - let bob = "bob"; - let carl = "carl"; - - // instantiate the contract - let admins = vec![alice.to_owned(), carl.to_owned()]; - let info = mock_info(bob, &[]); - contract - .instantiate(deps.as_mut(), mock_env(), info, admins, false) - .unwrap(); - - let freeze = WhitelistExecMsg::Freeze {}; - let msgs = vec![ - BankMsg::Send { - to_address: bob.to_string(), - amount: coins(10000, "DAI"), - } - .into(), - WasmMsg::Execute { - contract_addr: "some contract".into(), - msg: to_binary(&freeze).unwrap(), - funds: vec![], - } - .into(), - ]; - - // bob cannot execute them - let info = mock_info(bob, &[]); - let err = contract - .execute(deps.as_mut(), mock_env(), info, msgs.clone()) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // but carl can - let info = mock_info(carl, &[]); - let res = contract - .execute(deps.as_mut(), mock_env(), info, msgs.clone()) - .unwrap(); - assert_eq!( - res.messages, - msgs.into_iter().map(SubMsg::new).collect::>() - ); - assert_eq!(res.attributes, [("action", "execute")]); - } - - #[test] - fn execute_custom_messages_works() { - let contract = Cw1WhitelistContract::::new(); - let mut deps = mock_dependencies(); - let alice = "alice"; - - let admins = vec![alice.to_owned()]; - let info = mock_info(alice, &[]); - contract - .instantiate(deps.as_mut(), mock_env(), info, admins, false) - .unwrap(); - - let msgs = vec![CosmosMsg::Custom("msg".to_owned())]; - - let res = contract - .execute( - deps.as_mut(), - mock_env(), - mock_info(alice, &[]), - msgs.clone(), - ) - .unwrap(); - - assert_eq!( - res.messages, - msgs.into_iter().map(SubMsg::new).collect::>() - ); - } - - #[test] - fn can_execute_query_works() { - let contract = Cw1WhitelistContract::native(); - let mut deps = mock_dependencies(); - - let alice = "alice"; - let bob = "bob"; - - let anyone = "anyone"; - - // instantiate the contract - let admins = vec![alice.to_owned(), bob.to_owned()]; - let info = mock_info(anyone, &[]); - contract - .instantiate(deps.as_mut(), mock_env(), info, admins, false) - .unwrap(); - - // let us make some queries... different msg types by owner and by other - let send_msg = CosmosMsg::Bank(BankMsg::Send { - to_address: anyone.to_string(), - amount: coins(12345, "ushell"), - }); - let staking_msg = CosmosMsg::Staking(StakingMsg::Delegate { - validator: anyone.to_string(), - amount: coin(70000, "ureef"), - }); - - // owner can send - let res = contract - .can_execute( - deps.as_ref(), - mock_env(), - alice.to_owned(), - send_msg.clone(), - ) - .unwrap(); - assert!(res.can_execute); - - // owner can stake - let res = contract - .can_execute( - deps.as_ref(), - mock_env(), - bob.to_owned(), - staking_msg.clone(), - ) - .unwrap(); - assert!(res.can_execute); - - // anyone cannot send - let res = contract - .can_execute(deps.as_ref(), mock_env(), anyone.to_owned(), send_msg) - .unwrap(); - assert!(!res.can_execute); - - // anyone cannot stake - let res = contract - .can_execute(deps.as_ref(), mock_env(), anyone.to_owned(), staking_msg) - .unwrap(); - assert!(!res.can_execute); - } -} diff --git a/contracts/cw1-whitelist-ng/src/error.rs b/contracts/cw1-whitelist-ng/src/error.rs deleted file mode 100644 index 9a5e44903..000000000 --- a/contracts/cw1-whitelist-ng/src/error.rs +++ /dev/null @@ -1,11 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, -} diff --git a/contracts/cw1-whitelist-ng/src/interfaces.rs b/contracts/cw1-whitelist-ng/src/interfaces.rs deleted file mode 100644 index f07840584..000000000 --- a/contracts/cw1-whitelist-ng/src/interfaces.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::msg::AdminListResponse; -use cosmwasm_std::{CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response}; -use cw1::query::CanExecuteResponse; - -pub trait Cw1 { - type Error; - - fn execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msgs: Vec>, - ) -> Result, Self::Error>; - - fn can_execute( - &self, - deps: Deps, - env: Env, - sender: String, - msg: CosmosMsg, - ) -> Result; -} - -pub trait Whitelist { - type Error; - - fn freeze( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - ) -> Result, Self::Error>; - - fn update_admins( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - admins: Vec, - ) -> Result, Self::Error>; - - fn admin_list(&self, deps: Deps, env: Env) -> Result; -} diff --git a/contracts/cw1-whitelist-ng/src/lib.rs b/contracts/cw1-whitelist-ng/src/lib.rs deleted file mode 100644 index e2bbe8650..000000000 --- a/contracts/cw1-whitelist-ng/src/lib.rs +++ /dev/null @@ -1,64 +0,0 @@ -/*! -This may be the simplest implementation of [CW1](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1/README.md), a whitelist of addresses. -It contains a set of admins that are defined upon creation. -Any of those admins may `Execute` any message via the contract, -per the CW1 spec. - -To make this slighly less minimalistic, you can allow the admin set -to be mutable or immutable. If it is mutable, then any admin may -(a) change the admin set and (b) freeze it (making it immutable). - -While largely an example contract for CW1, this has various real-world use-cases, -such as a common account that is shared among multiple trusted devices, -or trading an entire account (used as 1 of 1 mutable). Most of the time, -this can be used as a framework to build your own, -more advanced cw1 implementations. - -For more information on this contract, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1-whitelist-ng/README.md). -*/ - -mod contract; -pub mod error; -pub mod interfaces; -pub mod msg; -pub mod multitest; -pub mod query; -pub mod state; - -#[cfg(not(feature = "library"))] -mod entry_points { - use crate::error::ContractError; - use crate::state::Cw1WhitelistContract; - use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; - - const CONTRACT: Cw1WhitelistContract = Cw1WhitelistContract::native(); - - #[entry_point] - pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Binary, - ) -> Result { - CONTRACT.entry_instantiate(deps, env, info, &msg) - } - - #[entry_point] - pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Binary, - ) -> Result { - CONTRACT.entry_execute(deps, env, info, &msg) - } - - #[entry_point] - pub fn query(deps: Deps, env: Env, msg: Binary) -> Result { - CONTRACT.entry_query(deps, env, &msg) - } -} - -#[cfg(not(feature = "library"))] -pub use entry_points::*; diff --git a/contracts/cw1-whitelist-ng/src/msg.rs b/contracts/cw1-whitelist-ng/src/msg.rs deleted file mode 100644 index 9b8826caf..000000000 --- a/contracts/cw1-whitelist-ng/src/msg.rs +++ /dev/null @@ -1,149 +0,0 @@ -// This whole file except `AdminListResponse` shall be generated form contract traits and -// instantiate signature - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - to_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdError, -}; - -use crate::error::ContractError; -use crate::interfaces::*; -use crate::state::Cw1WhitelistContract; - -#[derive(Serialize, Deserialize, JsonSchema)] -pub struct InstantiateMsg { - pub admins: Vec, - pub mutable: bool, -} - -impl InstantiateMsg { - pub fn dispatch( - self, - deps: DepsMut, - env: Env, - info: MessageInfo, - contract: &Cw1WhitelistContract, - ) -> Result, ContractError> { - let InstantiateMsg { admins, mutable } = self; - contract.instantiate(deps, env, info, admins, mutable) - } -} - -#[cw_serde] -pub enum Cw1ExecMsg { - /// Execute requests the contract to re-dispatch all these messages with the - /// contract's address as sender. Every implementation has it's own logic to - /// determine in - Execute { msgs: Vec> }, -} - -#[cw_serde] -pub enum WhitelistExecMsg { - /// Freeze will make a mutable contract immutable, must be called by an admin - Freeze {}, - /// UpdateAdmins will change the admin set of the contract, must be called by an existing admin, - /// and only works if the contract is mutable - UpdateAdmins { admins: Vec }, -} - -impl Cw1ExecMsg { - pub fn dispatch( - self, - deps: DepsMut, - env: Env, - info: MessageInfo, - contract: &Contract, - ) -> Result, Contract::Error> - where - Contract: Cw1, - { - use Cw1ExecMsg::*; - - match self { - Execute { msgs } => contract.execute(deps, env, info, msgs), - } - } -} - -impl WhitelistExecMsg { - pub fn dispatch( - self, - deps: DepsMut, - env: Env, - info: MessageInfo, - contract: &Contract, - ) -> Result, Contract::Error> - where - Contract: Whitelist, - { - use WhitelistExecMsg::*; - - match self { - Freeze {} => contract.freeze(deps, env, info), - UpdateAdmins { admins } => contract.update_admins(deps, env, info, admins), - } - } -} - -#[cw_serde] -pub enum Cw1QueryMsg { - /// Checks permissions of the caller on this proxy. - /// If CanExecute returns true then a call to `Execute` with the same message, - /// before any further state changes, should also succeed. - CanExecute { sender: String, msg: CosmosMsg }, -} - -impl Cw1QueryMsg { - pub fn dispatch( - self, - deps: Deps, - env: Env, - contract: &Contract, - ) -> Result - where - Contract: Cw1, - Contract::Error: From, - { - use Cw1QueryMsg::*; - - match self { - CanExecute { sender, msg } => to_binary(&contract.can_execute(deps, env, sender, msg)?), - } - .map_err(Contract::Error::from) - } -} - -#[cw_serde] -pub enum WhitelistQueryMsg { - /// Shows all admins and whether or not it is mutable - AdminList {}, -} - -impl WhitelistQueryMsg { - pub fn dispatch( - self, - deps: Deps, - env: Env, - contract: &Contract, - ) -> Result - where - Contract: Whitelist, - Contract::Error: From, - { - use WhitelistQueryMsg::*; - - match self { - AdminList {} => to_binary(&contract.admin_list(deps, env)?), - } - .map_err(Contract::Error::from) - } -} - -#[cw_serde] -pub struct AdminListResponse { - pub admins: Vec, - pub mutable: bool, -} diff --git a/contracts/cw1-whitelist-ng/src/multitest.rs b/contracts/cw1-whitelist-ng/src/multitest.rs deleted file mode 100644 index 9ade2a89d..000000000 --- a/contracts/cw1-whitelist-ng/src/multitest.rs +++ /dev/null @@ -1,44 +0,0 @@ -#[cfg(any(test, feature = "multitest"))] -pub mod contract; - -#[cfg(test)] -mod test { - use cosmwasm_std::{to_binary, Addr, CosmosMsg, WasmMsg}; - use cw_multi_test::AppBuilder; - - use crate::msg::WhitelistExecMsg; - use crate::state::Cw1WhitelistContract; - - use super::contract::Cw1WhitelistProxy; - - #[test] - fn proxy_freeze_message() { - let mut app = AppBuilder::new().build(|_, _, _| ()); - let contract_id = app.store_code(Box::new(Cw1WhitelistContract::new())); - let owner = Addr::unchecked("owner"); - - let proxy = Cw1WhitelistProxy::instantiate(&mut app, contract_id, &owner, &[]) - .with_label("Proxy") - .with_args(vec![owner.to_string()], true) - .unwrap(); - - let remote = Cw1WhitelistProxy::instantiate(&mut app, contract_id, &owner, &[]) - .with_label("Remote") - .with_args(vec![proxy.addr().into()], true) - .unwrap(); - - assert_ne!(proxy, remote); - - proxy - .cw1_exec(&mut app, &owner, &[]) - .execute(vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: remote.addr().into(), - msg: to_binary(&WhitelistExecMsg::Freeze {}).unwrap(), - funds: vec![], - })]) - .unwrap(); - - let resp = remote.whitelist_querier(&app.wrap()).admin_list().unwrap(); - assert!(!resp.mutable); - } -} diff --git a/contracts/cw1-whitelist-ng/src/multitest/contract.rs b/contracts/cw1-whitelist-ng/src/multitest/contract.rs deleted file mode 100644 index b14fcb354..000000000 --- a/contracts/cw1-whitelist-ng/src/multitest/contract.rs +++ /dev/null @@ -1,239 +0,0 @@ -use crate::msg::*; -use crate::query::*; -use crate::state::Cw1WhitelistContract; -use anyhow::{bail, Result as AnyResult}; -use cosmwasm_std::CustomMsg; -use cosmwasm_std::{ - Addr, Binary, Coin, CosmosMsg, CustomQuery, DepsMut, Env, MessageInfo, QuerierWrapper, Reply, - Response, -}; -use cw_multi_test::{AppResponse, Contract, Executor}; -use schemars::JsonSchema; -use serde::de::DeserializeOwned; - -impl Contract for Cw1WhitelistContract -where - T: Clone + std::fmt::Debug + PartialEq + JsonSchema + DeserializeOwned, -{ - fn instantiate( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - self.entry_instantiate(deps, env, info, &msg) - .map_err(Into::into) - } - - fn execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - self.entry_execute(deps, env, info, &msg) - .map_err(Into::into) - } - - fn query(&self, deps: cosmwasm_std::Deps, env: Env, msg: Vec) -> AnyResult { - self.entry_query(deps, env, &msg).map_err(Into::into) - } - - fn sudo(&self, _deps: DepsMut, _env: Env, _msg: Vec) -> AnyResult> { - bail!("sudo not implemented for contract") - } - - fn reply(&self, _deps: DepsMut, _env: Env, _msg: Reply) -> AnyResult> { - bail!("reply not implemented for contract") - } - - fn migrate(&self, _deps: DepsMut, _env: Env, _msg: Vec) -> AnyResult> { - bail!("migrate not implemented for contract") - } -} - -#[derive(PartialEq, Eq, Debug)] -#[must_use] -pub struct Cw1Executor<'a, App> { - addr: Addr, - app: &'a mut App, - sender: Addr, - send_funds: &'a [Coin], -} - -impl<'a, App> Cw1Executor<'a, App> { - pub fn new(addr: Addr, app: &'a mut App, sender: Addr, send_funds: &'a [Coin]) -> Self { - Self { - addr, - app, - sender, - send_funds, - } - } - - pub fn execute(self, msgs: Vec>) -> AnyResult - where - C: CustomMsg + 'static, - App: Executor, - { - self.app.execute_contract( - self.sender, - self.addr, - &Cw1ExecMsg::Execute { msgs }, - self.send_funds, - ) - } -} - -#[derive(PartialEq, Eq, Debug)] -#[must_use] -pub struct WhitelistExecutor<'a, App> { - addr: Addr, - app: &'a mut App, - sender: Addr, - send_funds: &'a [Coin], -} - -impl<'a, App> WhitelistExecutor<'a, App> { - pub fn new(addr: Addr, app: &'a mut App, sender: Addr, send_funds: &'a [Coin]) -> Self { - Self { - addr, - app, - sender, - send_funds, - } - } - - pub fn freeze(self) -> AnyResult - where - C: CustomMsg + 'static, - App: Executor, - { - self.app.execute_contract( - self.sender, - self.addr, - &WhitelistExecMsg::Freeze {}, - self.send_funds, - ) - } - - pub fn update_admins(self, admins: Vec) -> AnyResult - where - C: CustomMsg + 'static, - App: Executor, - { - self.app.execute_contract( - self.sender, - self.addr, - &WhitelistExecMsg::UpdateAdmins { admins }, - self.send_funds, - ) - } -} - -#[derive(PartialEq, Eq, Debug)] -#[must_use] -pub struct Instantiator<'a, App> { - code_id: u64, - app: &'a mut App, - sender: Addr, - send_funds: &'a [Coin], - label: String, - admin: Option, -} - -impl<'a, App> Instantiator<'a, App> { - pub fn new(code_id: u64, app: &'a mut App, sender: Addr, send_funds: &'a [Coin]) -> Self { - Self { - code_id, - app, - sender, - send_funds, - label: "Cw1Whitelist".to_owned(), - admin: None, - } - } - - pub fn with_label(mut self, label: &str) -> Self { - self.label = label.to_owned(); - self - } - - pub fn with_admin(mut self, admin: &str) -> Self { - self.admin = Some(admin.to_owned()); - self - } - - pub fn with_args(self, admins: Vec, mutable: bool) -> AnyResult - where - C: CustomMsg + 'static, - App: Executor, - { - let addr = self.app.instantiate_contract( - self.code_id, - self.sender, - &InstantiateMsg { admins, mutable }, - self.send_funds, - self.label, - self.admin, - )?; - - Ok(Cw1WhitelistProxy(addr)) - } -} - -// Proxy for direct execution in multitest. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Cw1WhitelistProxy(Addr); - -impl Cw1WhitelistProxy { - pub fn addr(&self) -> Addr { - self.0.clone() - } - - pub fn instantiate<'a, App>( - app: &'a mut App, - code_id: u64, - sender: &Addr, - send_funds: &'a [Coin], - ) -> Instantiator<'a, App> { - Instantiator::new(code_id, app, sender.clone(), send_funds) - } - - pub fn cw1_exec<'a, App>( - &self, - app: &'a mut App, - sender: &Addr, - send_funds: &'a [Coin], - ) -> Cw1Executor<'a, App> { - Cw1Executor::new(self.0.clone(), app, sender.clone(), send_funds) - } - - pub fn whitelist_exec<'a, App>( - &self, - app: &'a mut App, - sender: &Addr, - send_funds: &'a [Coin], - ) -> WhitelistExecutor<'a, App> { - WhitelistExecutor::new(self.0.clone(), app, sender.clone(), send_funds) - } - - pub fn cw1_querier<'a, C>(&'a self, querier: &'a QuerierWrapper<'a, C>) -> Cw1Querier<'a, C> - where - C: CustomQuery, - { - Cw1Querier::new(&self.0, querier) - } - - pub fn whitelist_querier<'a, C>( - &'a self, - querier: &'a QuerierWrapper<'a, C>, - ) -> WhitelistQuerier<'a, C> - where - C: CustomQuery, - { - WhitelistQuerier::new(&self.0, querier) - } -} diff --git a/contracts/cw1-whitelist-ng/src/query.rs b/contracts/cw1-whitelist-ng/src/query.rs deleted file mode 100644 index d8102ec2b..000000000 --- a/contracts/cw1-whitelist-ng/src/query.rs +++ /dev/null @@ -1,57 +0,0 @@ -// This whole thing is definitely to be easly generated from trait itself - -use cosmwasm_std::{Addr, CosmosMsg, CustomQuery, QuerierWrapper, StdResult}; -use cw1::CanExecuteResponse; -use serde::Serialize; - -use crate::msg::{AdminListResponse, Cw1QueryMsg, WhitelistQueryMsg}; - -#[must_use] -pub struct Cw1Querier<'a, C> -where - C: CustomQuery, -{ - addr: &'a Addr, - querier: &'a QuerierWrapper<'a, C>, -} - -impl<'a, C> Cw1Querier<'a, C> -where - C: CustomQuery, -{ - pub fn new(addr: &'a Addr, querier: &'a QuerierWrapper<'a, C>) -> Self { - Self { addr, querier } - } - - pub fn can_execute( - &self, - sender: String, - msg: CosmosMsg, - ) -> StdResult { - self.querier - .query_wasm_smart(self.addr.as_str(), &Cw1QueryMsg::CanExecute { sender, msg }) - } -} - -#[must_use] -pub struct WhitelistQuerier<'a, C> -where - C: CustomQuery, -{ - addr: &'a Addr, - querier: &'a QuerierWrapper<'a, C>, -} - -impl<'a, C> WhitelistQuerier<'a, C> -where - C: CustomQuery, -{ - pub fn new(addr: &'a Addr, querier: &'a QuerierWrapper<'a, C>) -> Self { - Self { addr, querier } - } - - pub fn admin_list(&self) -> StdResult { - self.querier - .query_wasm_smart(self.addr.as_str(), &WhitelistQueryMsg::AdminList {}) - } -} diff --git a/contracts/cw1-whitelist-ng/src/state.rs b/contracts/cw1-whitelist-ng/src/state.rs deleted file mode 100644 index 336fdfdda..000000000 --- a/contracts/cw1-whitelist-ng/src/state.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::marker::PhantomData; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{Addr, Empty}; -use cw_storage_plus::Item; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] -pub struct AdminList { - pub admins: Vec, - pub mutable: bool, -} - -impl AdminList { - /// returns true if the address is a registered admin - pub fn is_admin(&self, addr: &str) -> bool { - self.admins.iter().any(|a| a.as_ref() == addr) - } - - /// returns true if the address is a registered admin and the config is mutable - pub fn can_modify(&self, addr: &str) -> bool { - self.mutable && self.is_admin(addr) - } -} - -pub struct Cw1WhitelistContract { - // I am pretty sure that just form this with some proper hint attributes it would be possible - // to provide helpers for raw queries, this might be fun idea - pub(crate) admin_list: Item<'static, AdminList>, - _msg: PhantomData, -} - -impl Cw1WhitelistContract { - // Native form of this contract as it is to be created in entry points - pub const fn native() -> Self { - Self::new() - } -} - -impl Cw1WhitelistContract { - pub const fn new() -> Self { - Self { - admin_list: Item::new("admin_list"), - _msg: PhantomData, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn is_admin() { - let admins: Vec<_> = vec!["bob", "paul", "john"] - .into_iter() - .map(Addr::unchecked) - .collect(); - let config = AdminList { - admins: admins.clone(), - mutable: false, - }; - - assert!(config.is_admin(admins[0].as_ref())); - assert!(config.is_admin(admins[2].as_ref())); - assert!(!config.is_admin("other")); - } - - #[test] - fn can_modify() { - let alice = Addr::unchecked("alice"); - let bob = Addr::unchecked("bob"); - - // admin can modify mutable contract - let config = AdminList { - admins: vec![bob.clone()], - mutable: true, - }; - assert!(!config.can_modify(alice.as_ref())); - assert!(config.can_modify(bob.as_ref())); - - // no one can modify an immutable contract - let config = AdminList { - admins: vec![alice.clone()], - mutable: false, - }; - assert!(!config.can_modify(alice.as_ref())); - assert!(!config.can_modify(bob.as_ref())); - } -} From e64af4a7d4fb79cf43fdf12a6ff74b9413e17148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 12 Oct 2022 14:10:40 +0200 Subject: [PATCH 501/631] Generic query for cw3 unification --- packages/cw3/src/query.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/cw3/src/query.rs b/packages/cw3/src/query.rs index f1a5b9383..a20305489 100644 --- a/packages/cw3/src/query.rs +++ b/packages/cw3/src/query.rs @@ -86,8 +86,11 @@ pub enum Status { } #[cw_serde] -pub struct ProposalListResponse { - pub proposals: Vec, +pub struct ProposalListResponse +where + T: Clone + fmt::Debug + PartialEq + JsonSchema, +{ + pub proposals: Vec>, } #[cw_serde] From 5bb4f813d57a6969dc9fa4e0e371b0e814e07962 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 18:23:41 +0200 Subject: [PATCH 502/631] Remove cosmwasm-storage dependency Because cosmwasm-storage is going to be deprecated --- Cargo.lock | 11 - packages/multi-test/Cargo.toml | 1 - packages/multi-test/src/bank.rs | 2 +- packages/multi-test/src/lib.rs | 1 + packages/multi-test/src/prefixed_storage.rs | 185 +++++++++++++++ .../src/prefixed_storage/length_prefixed.rs | 176 ++++++++++++++ .../src/prefixed_storage/namespace_helpers.rs | 220 ++++++++++++++++++ packages/multi-test/src/wasm.rs | 2 +- 8 files changed, 584 insertions(+), 14 deletions(-) create mode 100644 packages/multi-test/src/prefixed_storage.rs create mode 100644 packages/multi-test/src/prefixed_storage/length_prefixed.rs create mode 100644 packages/multi-test/src/prefixed_storage/namespace_helpers.rs diff --git a/Cargo.lock b/Cargo.lock index 0f790ab7c..3a57deba7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,16 +235,6 @@ dependencies = [ "uint", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3205d5210ba4c7b7cc7329b9607c37d00dc08263c2479fd99541a2194ebe3b22" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cpufeatures" version = "0.2.4" @@ -417,7 +407,6 @@ version = "0.15.1" dependencies = [ "anyhow", "cosmwasm-std", - "cosmwasm-storage", "cw-storage-plus", "cw-utils", "derivative", diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 916ca0ef5..7a48b49c6 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -20,7 +20,6 @@ backtrace = ["anyhow/backtrace"] cw-utils = { path = "../../packages/utils", version = "0.15.1" } cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1"} cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cosmwasm-storage = "1.1.0" itertools = "0.10.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs index 71493d2c0..15cc66172 100644 --- a/packages/multi-test/src/bank.rs +++ b/packages/multi-test/src/bank.rs @@ -6,13 +6,13 @@ use cosmwasm_std::{ coin, to_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankMsg, BankQuery, Binary, BlockInfo, Coin, Event, Querier, Storage, }; -use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::Map; use cw_utils::NativeBalance; use crate::app::CosmosRouter; use crate::executor::AppResponse; use crate::module::Module; +use crate::prefixed_storage::{prefixed, prefixed_read}; const BALANCES: Map<&Addr, NativeBalance> = Map::new("balances"); diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 29ad0846e..662db3bb6 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -14,6 +14,7 @@ pub mod custom_handler; pub mod error; mod executor; mod module; +mod prefixed_storage; mod staking; mod test_helpers; mod transactions; diff --git a/packages/multi-test/src/prefixed_storage.rs b/packages/multi-test/src/prefixed_storage.rs new file mode 100644 index 000000000..b74e4d764 --- /dev/null +++ b/packages/multi-test/src/prefixed_storage.rs @@ -0,0 +1,185 @@ +mod length_prefixed; +mod namespace_helpers; + +use cosmwasm_std::Storage; +#[cfg(feature = "iterator")] +use cosmwasm_std::{Order, Record}; + +use length_prefixed::{to_length_prefixed, to_length_prefixed_nested}; +#[cfg(feature = "iterator")] +use namespace_helpers::range_with_prefix; +use namespace_helpers::{get_with_prefix, remove_with_prefix, set_with_prefix}; + +/// An alias of PrefixedStorage::new for less verbose usage +pub fn prefixed<'a>(storage: &'a mut dyn Storage, namespace: &[u8]) -> PrefixedStorage<'a> { + PrefixedStorage::new(storage, namespace) +} + +/// An alias of ReadonlyPrefixedStorage::new for less verbose usage +pub fn prefixed_read<'a>( + storage: &'a dyn Storage, + namespace: &[u8], +) -> ReadonlyPrefixedStorage<'a> { + ReadonlyPrefixedStorage::new(storage, namespace) +} + +pub struct PrefixedStorage<'a> { + storage: &'a mut dyn Storage, + prefix: Vec, +} + +impl<'a> PrefixedStorage<'a> { + pub fn new(storage: &'a mut dyn Storage, namespace: &[u8]) -> Self { + PrefixedStorage { + storage, + prefix: to_length_prefixed(namespace), + } + } + + // Nested namespaces as documented in + // https://github.com/webmaster128/key-namespacing#nesting + pub fn multilevel(storage: &'a mut dyn Storage, namespaces: &[&[u8]]) -> Self { + PrefixedStorage { + storage, + prefix: to_length_prefixed_nested(namespaces), + } + } +} + +impl<'a> Storage for PrefixedStorage<'a> { + fn get(&self, key: &[u8]) -> Option> { + get_with_prefix(self.storage, &self.prefix, key) + } + + fn set(&mut self, key: &[u8], value: &[u8]) { + set_with_prefix(self.storage, &self.prefix, key, value); + } + + fn remove(&mut self, key: &[u8]) { + remove_with_prefix(self.storage, &self.prefix, key); + } + + #[cfg(feature = "iterator")] + /// range allows iteration over a set of keys, either forwards or backwards + /// uses standard rust range notation, and eg db.range(b"foo"..b"bar") also works reverse + fn range<'b>( + &'b self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box + 'b> { + range_with_prefix(self.storage, &self.prefix, start, end, order) + } +} + +pub struct ReadonlyPrefixedStorage<'a> { + storage: &'a dyn Storage, + prefix: Vec, +} + +impl<'a> ReadonlyPrefixedStorage<'a> { + pub fn new(storage: &'a dyn Storage, namespace: &[u8]) -> Self { + ReadonlyPrefixedStorage { + storage, + prefix: to_length_prefixed(namespace), + } + } + + // Nested namespaces as documented in + // https://github.com/webmaster128/key-namespacing#nesting + pub fn multilevel(storage: &'a dyn Storage, namespaces: &[&[u8]]) -> Self { + ReadonlyPrefixedStorage { + storage, + prefix: to_length_prefixed_nested(namespaces), + } + } +} + +impl<'a> Storage for ReadonlyPrefixedStorage<'a> { + fn get(&self, key: &[u8]) -> Option> { + get_with_prefix(self.storage, &self.prefix, key) + } + + fn set(&mut self, _key: &[u8], _value: &[u8]) { + unimplemented!(); + } + + fn remove(&mut self, _key: &[u8]) { + unimplemented!(); + } + + #[cfg(feature = "iterator")] + /// range allows iteration over a set of keys, either forwards or backwards + fn range<'b>( + &'b self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box + 'b> { + range_with_prefix(self.storage, &self.prefix, start, end, order) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::MockStorage; + + #[test] + fn prefixed_storage_set_and_get() { + let mut storage = MockStorage::new(); + + // set + let mut s1 = PrefixedStorage::new(&mut storage, b"foo"); + s1.set(b"bar", b"gotcha"); + assert_eq!(storage.get(b"\x00\x03foobar").unwrap(), b"gotcha".to_vec()); + + // get + let s2 = PrefixedStorage::new(&mut storage, b"foo"); + assert_eq!(s2.get(b"bar"), Some(b"gotcha".to_vec())); + assert_eq!(s2.get(b"elsewhere"), None); + } + + #[test] + fn prefixed_storage_multilevel_set_and_get() { + let mut storage = MockStorage::new(); + + // set + let mut bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]); + bar.set(b"baz", b"winner"); + assert_eq!( + storage.get(b"\x00\x03foo\x00\x03barbaz").unwrap(), + b"winner".to_vec() + ); + + // get + let bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]); + assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec())); + assert_eq!(bar.get(b"elsewhere"), None); + } + + #[test] + fn readonly_prefixed_storage_get() { + let mut storage = MockStorage::new(); + storage.set(b"\x00\x03foobar", b"gotcha"); + + // try readonly correctly + let s1 = ReadonlyPrefixedStorage::new(&storage, b"foo"); + assert_eq!(s1.get(b"bar"), Some(b"gotcha".to_vec())); + assert_eq!(s1.get(b"elsewhere"), None); + + // no collisions with other prefixes + let s2 = ReadonlyPrefixedStorage::new(&storage, b"fo"); + assert_eq!(s2.get(b"obar"), None); + } + + #[test] + fn readonly_prefixed_storage_multilevel_get() { + let mut storage = MockStorage::new(); + storage.set(b"\x00\x03foo\x00\x03barbaz", b"winner"); + + let bar = ReadonlyPrefixedStorage::multilevel(&storage, &[b"foo", b"bar"]); + assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec())); + assert_eq!(bar.get(b"elsewhere"), None); + } +} diff --git a/packages/multi-test/src/prefixed_storage/length_prefixed.rs b/packages/multi-test/src/prefixed_storage/length_prefixed.rs new file mode 100644 index 000000000..5d97b3b41 --- /dev/null +++ b/packages/multi-test/src/prefixed_storage/length_prefixed.rs @@ -0,0 +1,176 @@ +//! This module is an implemention of a namespacing scheme described +//! in https://github.com/webmaster128/key-namespacing#length-prefixed-keys +//! +//! Everything in this file is only responsible for building such keys +//! and is in no way specific to any kind of storage. + +/// Calculates the raw key prefix for a given namespace as documented +/// in https://github.com/webmaster128/key-namespacing#length-prefixed-keys +pub fn to_length_prefixed(namespace: &[u8]) -> Vec { + let mut out = Vec::with_capacity(namespace.len() + 2); + out.extend_from_slice(&encode_length(namespace)); + out.extend_from_slice(namespace); + out +} + +/// Calculates the raw key prefix for a given nested namespace +/// as documented in https://github.com/webmaster128/key-namespacing#nesting +pub fn to_length_prefixed_nested(namespaces: &[&[u8]]) -> Vec { + let mut size = 0; + for &namespace in namespaces { + size += namespace.len() + 2; + } + + let mut out = Vec::with_capacity(size); + for &namespace in namespaces { + out.extend_from_slice(&encode_length(namespace)); + out.extend_from_slice(namespace); + } + out +} + +/// Encodes the length of a given namespace as a 2 byte big endian encoded integer +fn encode_length(namespace: &[u8]) -> [u8; 2] { + if namespace.len() > 0xFFFF { + panic!("only supports namespaces up to length 0xFFFF") + } + let length_bytes = (namespace.len() as u32).to_be_bytes(); + [length_bytes[2], length_bytes[3]] +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn to_length_prefixed_works() { + assert_eq!(to_length_prefixed(b""), b"\x00\x00"); + assert_eq!(to_length_prefixed(b"a"), b"\x00\x01a"); + assert_eq!(to_length_prefixed(b"ab"), b"\x00\x02ab"); + assert_eq!(to_length_prefixed(b"abc"), b"\x00\x03abc"); + } + + #[test] + fn to_length_prefixed_works_for_long_prefix() { + let long_namespace1 = vec![0; 256]; + let prefix1 = to_length_prefixed(&long_namespace1); + assert_eq!(prefix1.len(), 256 + 2); + assert_eq!(&prefix1[0..2], b"\x01\x00"); + + let long_namespace2 = vec![0; 30000]; + let prefix2 = to_length_prefixed(&long_namespace2); + assert_eq!(prefix2.len(), 30000 + 2); + assert_eq!(&prefix2[0..2], b"\x75\x30"); + + let long_namespace3 = vec![0; 0xFFFF]; + let prefix3 = to_length_prefixed(&long_namespace3); + assert_eq!(prefix3.len(), 0xFFFF + 2); + assert_eq!(&prefix3[0..2], b"\xFF\xFF"); + } + + #[test] + #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] + fn to_length_prefixed_panics_for_too_long_prefix() { + let limit = 0xFFFF; + let long_namespace = vec![0; limit + 1]; + to_length_prefixed(&long_namespace); + } + + #[test] + fn to_length_prefixed_calculates_capacity_correctly() { + // Those tests cannot guarantee the required capacity was calculated correctly before + // the vector allocation but increase the likelyhood of a proper implementation. + + let key = to_length_prefixed(b""); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed(b"h"); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed(b"hij"); + assert_eq!(key.capacity(), key.len()); + } + + #[test] + fn to_length_prefixed_nested_works() { + assert_eq!(to_length_prefixed_nested(&[]), b""); + assert_eq!(to_length_prefixed_nested(&[b""]), b"\x00\x00"); + assert_eq!(to_length_prefixed_nested(&[b"", b""]), b"\x00\x00\x00\x00"); + + assert_eq!(to_length_prefixed_nested(&[b"a"]), b"\x00\x01a"); + assert_eq!( + to_length_prefixed_nested(&[b"a", b"ab"]), + b"\x00\x01a\x00\x02ab" + ); + assert_eq!( + to_length_prefixed_nested(&[b"a", b"ab", b"abc"]), + b"\x00\x01a\x00\x02ab\x00\x03abc" + ); + } + + #[test] + fn to_length_prefixed_nested_allows_many_long_namespaces() { + // The 0xFFFF limit is for each namespace, not for the combination of them + + let long_namespace1 = vec![0xaa; 0xFFFD]; + let long_namespace2 = vec![0xbb; 0xFFFE]; + let long_namespace3 = vec![0xcc; 0xFFFF]; + + let prefix = + to_length_prefixed_nested(&[&long_namespace1, &long_namespace2, &long_namespace3]); + assert_eq!(&prefix[0..2], b"\xFF\xFD"); + assert_eq!(&prefix[2..(2 + 0xFFFD)], long_namespace1.as_slice()); + assert_eq!(&prefix[(2 + 0xFFFD)..(2 + 0xFFFD + 2)], b"\xFF\xFe"); + assert_eq!( + &prefix[(2 + 0xFFFD + 2)..(2 + 0xFFFD + 2 + 0xFFFE)], + long_namespace2.as_slice() + ); + assert_eq!( + &prefix[(2 + 0xFFFD + 2 + 0xFFFE)..(2 + 0xFFFD + 2 + 0xFFFE + 2)], + b"\xFF\xFf" + ); + assert_eq!( + &prefix[(2 + 0xFFFD + 2 + 0xFFFE + 2)..(2 + 0xFFFD + 2 + 0xFFFE + 2 + 0xFFFF)], + long_namespace3.as_slice() + ); + } + + #[test] + fn to_length_prefixed_nested_calculates_capacity_correctly() { + // Those tests cannot guarantee the required capacity was calculated correctly before + // the vector allocation but increase the likelyhood of a proper implementation. + + let key = to_length_prefixed_nested(&[]); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed_nested(&[b""]); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed_nested(&[b"a"]); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed_nested(&[b"a", b"bc"]); + assert_eq!(key.capacity(), key.len()); + + let key = to_length_prefixed_nested(&[b"a", b"bc", b"def"]); + assert_eq!(key.capacity(), key.len()); + } + + #[test] + fn encode_length_works() { + assert_eq!(encode_length(b""), *b"\x00\x00"); + assert_eq!(encode_length(b"a"), *b"\x00\x01"); + assert_eq!(encode_length(b"aa"), *b"\x00\x02"); + assert_eq!(encode_length(b"aaa"), *b"\x00\x03"); + assert_eq!(encode_length(&vec![1; 255]), *b"\x00\xff"); + assert_eq!(encode_length(&vec![1; 256]), *b"\x01\x00"); + assert_eq!(encode_length(&vec![1; 12345]), *b"\x30\x39"); + assert_eq!(encode_length(&vec![1; 65535]), *b"\xff\xff"); + } + + #[test] + #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] + fn encode_length_panics_for_large_values() { + encode_length(&vec![1; 65536]); + } +} diff --git a/packages/multi-test/src/prefixed_storage/namespace_helpers.rs b/packages/multi-test/src/prefixed_storage/namespace_helpers.rs new file mode 100644 index 000000000..2e69605de --- /dev/null +++ b/packages/multi-test/src/prefixed_storage/namespace_helpers.rs @@ -0,0 +1,220 @@ +use cosmwasm_std::Storage; +#[cfg(feature = "iterator")] +use cosmwasm_std::{Order, Record}; + +pub(crate) fn get_with_prefix( + storage: &dyn Storage, + namespace: &[u8], + key: &[u8], +) -> Option> { + storage.get(&concat(namespace, key)) +} + +pub(crate) fn set_with_prefix( + storage: &mut dyn Storage, + namespace: &[u8], + key: &[u8], + value: &[u8], +) { + storage.set(&concat(namespace, key), value); +} + +pub(crate) fn remove_with_prefix(storage: &mut dyn Storage, namespace: &[u8], key: &[u8]) { + storage.remove(&concat(namespace, key)); +} + +#[inline] +fn concat(namespace: &[u8], key: &[u8]) -> Vec { + let mut k = namespace.to_vec(); + k.extend_from_slice(key); + k +} + +#[cfg(feature = "iterator")] +pub(crate) fn range_with_prefix<'a>( + storage: &'a dyn Storage, + namespace: &[u8], + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, +) -> Box + 'a> { + // prepare start, end with prefix + let start = match start { + Some(s) => concat(namespace, s), + None => namespace.to_vec(), + }; + let end = match end { + Some(e) => concat(namespace, e), + // end is updating last byte by one + None => namespace_upper_bound(namespace), + }; + + // get iterator from storage + let base_iterator = storage.range(Some(&start), Some(&end), order); + + // make a copy for the closure to handle lifetimes safely + let prefix = namespace.to_vec(); + let mapped = base_iterator.map(move |(k, v)| (trim(&prefix, &k), v)); + Box::new(mapped) +} + +#[cfg(feature = "iterator")] +#[inline] +fn trim(namespace: &[u8], key: &[u8]) -> Vec { + key[namespace.len()..].to_vec() +} + +/// Returns a new vec of same length and last byte incremented by one +/// If last bytes are 255, we handle overflow up the chain. +/// If all bytes are 255, this returns wrong data - but that is never possible as a namespace +#[cfg(feature = "iterator")] +fn namespace_upper_bound(input: &[u8]) -> Vec { + let mut copy = input.to_vec(); + // zero out all trailing 255, increment first that is not such + for i in (0..input.len()).rev() { + if copy[i] == 255 { + copy[i] = 0; + } else { + copy[i] += 1; + break; + } + } + copy +} + +#[cfg(test)] +mod tests { + use super::super::length_prefixed::to_length_prefixed; + use super::*; + use cosmwasm_std::testing::MockStorage; + + #[test] + fn prefix_get_set() { + let mut storage = MockStorage::new(); + let prefix = to_length_prefixed(b"foo"); + + set_with_prefix(&mut storage, &prefix, b"bar", b"gotcha"); + let rfoo = get_with_prefix(&storage, &prefix, b"bar"); + assert_eq!(rfoo, Some(b"gotcha".to_vec())); + + // no collisions with other prefixes + let other_prefix = to_length_prefixed(b"fo"); + let collision = get_with_prefix(&storage, &other_prefix, b"obar"); + assert_eq!(collision, None); + } + + #[test] + #[cfg(feature = "iterator")] + fn range_works() { + let mut storage = MockStorage::new(); + let prefix = to_length_prefixed(b"foo"); + let other_prefix = to_length_prefixed(b"food"); + + // set some values in this range + set_with_prefix(&mut storage, &prefix, b"bar", b"none"); + set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); + + // set some values outside this range + set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); + + // ensure we get proper result from prefixed_range iterator + let mut iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); + let first = iter.next().unwrap(); + assert_eq!(first, (b"snowy".to_vec(), b"day".to_vec())); + let second = iter.next().unwrap(); + assert_eq!(second, (b"bar".to_vec(), b"none".to_vec())); + assert!(iter.next().is_none()); + + // ensure we get raw result from base range + let iter = storage.range(None, None, Order::Ascending); + assert_eq!(3, iter.count()); + + // foo comes first + let mut iter = storage.range(None, None, Order::Ascending); + let first = iter.next().unwrap(); + let expected_key = concat(&prefix, b"bar"); + assert_eq!(first, (expected_key, b"none".to_vec())); + } + + #[test] + #[cfg(feature = "iterator")] + fn range_with_prefix_wrapover() { + let mut storage = MockStorage::new(); + // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) + let prefix = to_length_prefixed(b"f\xff\xff"); + let other_prefix = to_length_prefixed(b"f\xff\x44"); + + // set some values in this range + set_with_prefix(&mut storage, &prefix, b"bar", b"none"); + set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); + + // set some values outside this range + set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); + + // ensure we get proper result from prefixed_range iterator + let iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); + let elements: Vec = iter.collect(); + assert_eq!( + elements, + vec![ + (b"snowy".to_vec(), b"day".to_vec()), + (b"bar".to_vec(), b"none".to_vec()), + ] + ); + } + + #[test] + #[cfg(feature = "iterator")] + fn range_with_start_end_set() { + let mut storage = MockStorage::new(); + // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) + let prefix = to_length_prefixed(b"f\xff\xff"); + let other_prefix = to_length_prefixed(b"f\xff\x44"); + + // set some values in this range + set_with_prefix(&mut storage, &prefix, b"bar", b"none"); + set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); + + // set some values outside this range + set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); + + // make sure start and end are applied properly + let res: Vec = + range_with_prefix(&storage, &prefix, Some(b"b"), Some(b"c"), Order::Ascending) + .collect(); + assert_eq!(res.len(), 1); + assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); + + // make sure start and end are applied properly + let res_count = range_with_prefix( + &storage, + &prefix, + Some(b"bas"), + Some(b"sno"), + Order::Ascending, + ) + .count(); + assert_eq!(res_count, 0); + + let res: Vec = + range_with_prefix(&storage, &prefix, Some(b"ant"), None, Order::Ascending).collect(); + assert_eq!(res.len(), 2); + assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); + assert_eq!(res[1], (b"snowy".to_vec(), b"day".to_vec())); + } + + #[test] + #[cfg(feature = "iterator")] + fn namespace_upper_bound_works() { + assert_eq!(namespace_upper_bound(b"bob"), b"boc".to_vec()); + assert_eq!(namespace_upper_bound(b"fo\xfe"), b"fo\xff".to_vec()); + assert_eq!(namespace_upper_bound(b"fo\xff"), b"fp\x00".to_vec()); + // multiple \xff roll over + assert_eq!( + namespace_upper_bound(b"fo\xff\xff\xff"), + b"fp\x00\x00\x00".to_vec() + ); + // \xff not at the end are ignored + assert_eq!(namespace_upper_bound(b"\xffabc"), b"\xffabd".to_vec()); + } +} diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 54afe9681..f615cc0df 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -8,7 +8,6 @@ use cosmwasm_std::{ QuerierWrapper, Record, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgResponse, SubMsgResult, TransactionInfo, WasmMsg, WasmQuery, }; -use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; use prost::Message; use schemars::JsonSchema; use serde::de::DeserializeOwned; @@ -20,6 +19,7 @@ use crate::app::{CosmosRouter, RouterQuerier}; use crate::contracts::Contract; use crate::error::Error; use crate::executor::AppResponse; +use crate::prefixed_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; use crate::transactions::transactional; use cosmwasm_std::testing::mock_wasmd_attr; From 01eed0491a8eeb575cdade0e23e860f042e5639b Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 18:26:22 +0200 Subject: [PATCH 503/631] Update README - remove `cosmwasm-storage` reference --- packages/storage-plus/README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md index 017dba7ba..b87b84223 100644 --- a/packages/storage-plus/README.md +++ b/packages/storage-plus/README.md @@ -30,10 +30,6 @@ for interacting with it without dealing with raw bytes. And `Map`, which allows you to store multiple unique typed objects under a prefix, indexed by a simple or compound (eg. `(&[u8], &[u8])`) primary key. -These correspond to the concepts represented in `cosmwasm_storage` by -`Singleton` and `Bucket`, but with a re-designed API and implementation -to require less typing for developers and less gas usage in the contracts. - ## Item The usage of an [`Item`](./src/item.rs) is pretty straight-forward. @@ -703,4 +699,4 @@ fn demo() -> StdResult<()> { Ok(()) } -``` \ No newline at end of file +``` From 972546f52f65f2c9df5d4c89eafa9cea300401fb Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 18:36:22 +0200 Subject: [PATCH 504/631] Remove `legacy_helpers.rs` --- packages/storage-plus/src/legacy_helpers.rs | 136 -------------------- 1 file changed, 136 deletions(-) delete mode 100644 packages/storage-plus/src/legacy_helpers.rs diff --git a/packages/storage-plus/src/legacy_helpers.rs b/packages/storage-plus/src/legacy_helpers.rs deleted file mode 100644 index d5931fa87..000000000 --- a/packages/storage-plus/src/legacy_helpers.rs +++ /dev/null @@ -1,136 +0,0 @@ -// This code is intentionally included not in lib.rs -// Most of it will be deleted. But maybe we want to borrow some chunks, so keeping them here. - -/// Calculates the raw key prefix for a given nested namespace -/// as documented in https://github.com/webmaster128/key-namespacing#nesting -pub(crate) fn to_length_prefixed_nested(namespaces: &[&[u8]]) -> Vec { - let mut size = 0; - for &namespace in namespaces { - size += namespace.len() + 2; - } - - let mut out = Vec::with_capacity(size); - for &namespace in namespaces { - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - } - out -} - -pub(crate) fn length_prefixed_with_key(namespace: &[u8], key: &[u8]) -> Vec { - let mut out = Vec::with_capacity(namespace.len() + 2 + key.len()); - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - out.extend_from_slice(key); - out -} - -pub(crate) fn get_with_prefix( - storage: &dyn Storage, - namespace: &[u8], - key: &[u8], -) -> Option> { - storage.get(&concat(namespace, key)) -} - -pub(crate) fn set_with_prefix( - storage: &mut dyn Storage, - namespace: &[u8], - key: &[u8], - value: &[u8], -) { - storage.set(&concat(namespace, key), value); -} - -pub(crate) fn remove_with_prefix(storage: &mut dyn Storage, namespace: &[u8], key: &[u8]) { - storage.remove(&concat(namespace, key)); -} - -#[cfg(test)] -mod legacy_test { - use super::*; - use crate::helpers::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn to_length_prefixed_nested_works() { - assert_eq!(to_length_prefixed_nested(&[]), b""); - assert_eq!(to_length_prefixed_nested(&[b""]), b"\x00\x00"); - assert_eq!(to_length_prefixed_nested(&[b"", b""]), b"\x00\x00\x00\x00"); - - assert_eq!(to_length_prefixed_nested(&[b"a"]), b"\x00\x01a"); - assert_eq!( - to_length_prefixed_nested(&[b"a", b"ab"]), - b"\x00\x01a\x00\x02ab" - ); - assert_eq!( - to_length_prefixed_nested(&[b"a", b"ab", b"abc"]), - b"\x00\x01a\x00\x02ab\x00\x03abc" - ); - } - - #[test] - fn to_length_prefixed_nested_allows_many_long_namespaces() { - // The 0xFFFF limit is for each namespace, not for the combination of them - - let long_namespace1 = vec![0xaa; 0xFFFD]; - let long_namespace2 = vec![0xbb; 0xFFFE]; - let long_namespace3 = vec![0xcc; 0xFFFF]; - - let prefix = - to_length_prefixed_nested(&[&long_namespace1, &long_namespace2, &long_namespace3]); - assert_eq!(&prefix[0..2], b"\xFF\xFD"); - assert_eq!(&prefix[2..(2 + 0xFFFD)], long_namespace1.as_slice()); - assert_eq!(&prefix[(2 + 0xFFFD)..(2 + 0xFFFD + 2)], b"\xFF\xFe"); - assert_eq!( - &prefix[(2 + 0xFFFD + 2)..(2 + 0xFFFD + 2 + 0xFFFE)], - long_namespace2.as_slice() - ); - assert_eq!( - &prefix[(2 + 0xFFFD + 2 + 0xFFFE)..(2 + 0xFFFD + 2 + 0xFFFE + 2)], - b"\xFF\xFf" - ); - assert_eq!( - &prefix[(2 + 0xFFFD + 2 + 0xFFFE + 2)..(2 + 0xFFFD + 2 + 0xFFFE + 2 + 0xFFFF)], - long_namespace3.as_slice() - ); - } - - #[test] - fn to_length_prefixed_nested_calculates_capacity_correctly() { - // Those tests cannot guarantee the required capacity was calculated correctly before - // the vector allocation but increase the likelyhood of a proper implementation. - - let key = to_length_prefixed_nested(&[]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b""]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a"]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a", b"bc"]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a", b"bc", b"def"]); - assert_eq!(key.capacity(), key.len()); - } - - - #[test] - fn prefix_get_set() { - let mut storage = MockStorage::new(); - let prefix = to_length_prefixed(b"foo"); - - set_with_prefix(&mut storage, &prefix, b"bar", b"gotcha"); - let rfoo = get_with_prefix(&storage, &prefix, b"bar"); - assert_eq!(rfoo, Some(b"gotcha".to_vec())); - - // no collisions with other prefixes - let other_prefix = to_length_prefixed(b"fo"); - let collision = get_with_prefix(&storage, &other_prefix, b"obar"); - assert_eq!(collision, None); - } - -} \ No newline at end of file From 0049fa7e6fbb86bf7fee9c746e269314ac536efe Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 19:15:47 +0200 Subject: [PATCH 505/631] cw4-group: regression test for duplicate members --- contracts/cw4-group/src/tests.rs | 69 +++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index ca542efa1..212438458 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -14,7 +14,7 @@ const USER1: &str = "somebody"; const USER2: &str = "else"; const USER3: &str = "funny"; -fn do_instantiate(deps: DepsMut) { +fn set_up(deps: DepsMut) { let msg = InstantiateMsg { admin: Some(INIT_ADMIN.into()), members: vec![ @@ -32,10 +32,19 @@ fn do_instantiate(deps: DepsMut) { instantiate(deps, mock_env(), info, msg).unwrap(); } +fn set_up_with_members(deps: DepsMut, members: impl Into>) { + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: members.into(), + }; + let info = mock_info("creator", &[]); + instantiate(deps, mock_env(), info, msg).unwrap(); +} + #[test] fn proper_instantiation() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); // it worked, let's query the state let res = ADMIN.query_admin(deps.as_ref()).unwrap(); @@ -48,7 +57,7 @@ fn proper_instantiation() { #[test] fn try_member_queries() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); assert_eq!(member1.weight, Some(11)); @@ -64,6 +73,46 @@ fn try_member_queries() { // TODO: assert the set is proper } +#[test] +fn duplicate_members() { + let mut deps = mock_dependencies(); + + set_up_with_members( + deps.as_mut(), + [ + Member { + addr: USER1.into(), + weight: 5, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + Member { + addr: USER1.into(), + weight: 6, + }, + ], + ); + + let res = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, res.weight); + + assert_eq!( + query_member(deps.as_ref(), USER1.into(), None) + .unwrap() + .weight, + Some(11) + ); + + assert_eq!( + query_member(deps.as_ref(), USER2.into(), None) + .unwrap() + .weight, + Some(6) + ); +} + fn assert_users( deps: &OwnedDeps, user1_weight: Option, @@ -99,7 +148,7 @@ fn assert_users( #[test] fn add_new_remove_old_member() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); // add a new one and remove existing one let add = vec![Member { @@ -148,7 +197,7 @@ fn add_new_remove_old_member() { fn add_old_remove_new_member() { // add will over-write and remove have no effect let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); // add a new one and remove existing one let add = vec![Member { @@ -174,7 +223,7 @@ fn add_old_remove_new_member() { fn add_and_remove_same_member() { // add will over-write and remove have no effect let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); // USER1 is updated and remove in the same call, we should remove this an add member3 let add = vec![ @@ -206,7 +255,7 @@ fn add_and_remove_same_member() { fn add_remove_hooks() { // add will over-write and remove have no effect let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); @@ -274,7 +323,7 @@ fn add_remove_hooks() { #[test] fn hooks_fire() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); @@ -332,7 +381,7 @@ fn hooks_fire() { fn raw_queries_work() { // add will over-write and remove have no effect let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); // get total from raw key let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); @@ -352,7 +401,7 @@ fn raw_queries_work() { #[test] fn total_at_height() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); + set_up(deps.as_mut()); let height = mock_env().block.height; From 7b7be21d6d1c92bbe561d031ab8c61ee0b157676 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 19:41:26 +0200 Subject: [PATCH 506/631] cw4-group: update duplicate member tests --- contracts/cw4-group/src/error.rs | 3 ++ contracts/cw4-group/src/tests.rs | 68 ++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/contracts/cw4-group/src/error.rs b/contracts/cw4-group/src/error.rs index a5d2f57cf..83016d3ce 100644 --- a/contracts/cw4-group/src/error.rs +++ b/contracts/cw4-group/src/error.rs @@ -19,4 +19,7 @@ pub enum ContractError { #[error("Unauthorized")] Unauthorized {}, + + #[error("Message contained duplicate member: {member}")] + DuplicateMembers { member: String }, } diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index 212438458..9bd483586 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -8,6 +8,7 @@ use crate::contract::{ }; use crate::msg::{ExecuteMsg, InstantiateMsg}; use crate::state::{ADMIN, HOOKS}; +use crate::ContractError; const INIT_ADMIN: &str = "juan"; const USER1: &str = "somebody"; @@ -32,15 +33,6 @@ fn set_up(deps: DepsMut) { instantiate(deps, mock_env(), info, msg).unwrap(); } -fn set_up_with_members(deps: DepsMut, members: impl Into>) { - let msg = InstantiateMsg { - admin: Some(INIT_ADMIN.into()), - members: members.into(), - }; - let info = mock_info("creator", &[]); - instantiate(deps, mock_env(), info, msg).unwrap(); -} - #[test] fn proper_instantiation() { let mut deps = mock_dependencies(); @@ -74,12 +66,12 @@ fn try_member_queries() { } #[test] -fn duplicate_members() { +fn duplicate_members_instantiation() { let mut deps = mock_dependencies(); - set_up_with_members( - deps.as_mut(), - [ + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ Member { addr: USER1.into(), weight: 5, @@ -93,23 +85,49 @@ fn duplicate_members() { weight: 6, }, ], + }; + let info = mock_info("creator", &[]); + let err = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::DuplicateMembers { + member: USER1.to_string() + } ); +} - let res = query_total_weight(deps.as_ref(), None).unwrap(); - assert_eq!(17, res.weight); +#[test] +fn duplicate_members_execution() { + let mut deps = mock_dependencies(); - assert_eq!( - query_member(deps.as_ref(), USER1.into(), None) - .unwrap() - .weight, - Some(11) - ); + set_up(deps.as_mut()); + + let add = vec![ + Member { + addr: USER3.into(), + weight: 15, + }, + Member { + addr: USER3.into(), + weight: 11, + }, + ]; + + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(INIT_ADMIN), + add, + vec![], + ) + .unwrap_err(); assert_eq!( - query_member(deps.as_ref(), USER2.into(), None) - .unwrap() - .weight, - Some(6) + err, + ContractError::DuplicateMembers { + member: USER3.to_string() + } ); } From 11845328fcbb6a08a0e71b5912fd2b9a2af29147 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 20:28:12 +0200 Subject: [PATCH 507/631] cw4-group: throw error on duplicate additions --- contracts/cw4-group/src/contract.rs | 11 +++++++++-- contracts/cw4-group/src/helpers.rs | 16 +++++++++++++++- contracts/cw4-group/src/tests.rs | 6 +++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index d2111a47e..711b6b655 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -13,6 +13,7 @@ use cw_storage_plus::Bound; use cw_utils::maybe_addr; use crate::error::ContractError; +use crate::helpers::validate_unique_members; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{ADMIN, HOOKS, MEMBERS, TOTAL}; @@ -39,9 +40,12 @@ pub fn instantiate( pub fn create( mut deps: DepsMut, admin: Option, - members: Vec, + mut members: Vec, height: u64, ) -> Result<(), ContractError> { + validate_unique_members(&mut members)?; + let members = members; // let go of mutability + let admin_addr = admin .map(|admin| deps.api.addr_validate(&admin)) .transpose()?; @@ -122,9 +126,12 @@ pub fn update_members( deps: DepsMut, height: u64, sender: Addr, - to_add: Vec, + mut to_add: Vec, to_remove: Vec, ) -> Result { + validate_unique_members(&mut to_add)?; + let to_add = to_add; // let go of mutability + ADMIN.assert_admin(deps.as_ref(), &sender)?; let mut total = Uint64::from(TOTAL.load(deps.storage)?); diff --git a/contracts/cw4-group/src/helpers.rs b/contracts/cw4-group/src/helpers.rs index b7719d90b..10e3edf99 100644 --- a/contracts/cw4-group/src/helpers.rs +++ b/contracts/cw4-group/src/helpers.rs @@ -4,7 +4,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use cw4::{Cw4Contract, Member}; -use crate::msg::ExecuteMsg; +use crate::{msg::ExecuteMsg, ContractError}; /// Cw4GroupContract is a wrapper around Cw4Contract that provides a lot of helpers /// for working with cw4-group contracts. @@ -40,3 +40,17 @@ impl Cw4GroupContract { self.encode_msg(msg) } } + +/// Sorts the slice and verifies all member addresses are unique. +pub fn validate_unique_members(members: &mut [Member]) -> Result<(), ContractError> { + members.sort_by(|a, b| a.addr.cmp(&b.addr)); + for (a, b) in members.iter().zip(members.iter().skip(1)) { + if a.addr == b.addr { + return Err(ContractError::DuplicateMembers { + member: a.addr.clone(), + }); + } + } + + Ok(()) +} diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index 9bd483586..d18189d9c 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -384,14 +384,18 @@ fn hooks_fire() { // ensure 2 messages for the 2 hooks assert_eq!(res.messages.len(), 2); // same order as in the message (adds first, then remove) + // order of added users is not guaranteed to be preserved let diffs = vec![ - MemberDiff::new(USER1, Some(11), Some(20)), MemberDiff::new(USER3, None, Some(5)), + MemberDiff::new(USER1, Some(11), Some(20)), MemberDiff::new(USER2, Some(6), None), ]; let hook_msg = MemberChangedHookMsg { diffs }; let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); + dbg!(&res.messages); + dbg!(&msg1); + dbg!(&msg2); assert_eq!(res.messages, vec![msg1, msg2]); } From 050f3536305b8c69d0e2508da31f7f66f4b5d628 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 20:29:13 +0200 Subject: [PATCH 508/631] style --- contracts/cw4-group/src/error.rs | 2 +- contracts/cw4-group/src/helpers.rs | 2 +- contracts/cw4-group/src/tests.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/cw4-group/src/error.rs b/contracts/cw4-group/src/error.rs index 83016d3ce..bd5acb30f 100644 --- a/contracts/cw4-group/src/error.rs +++ b/contracts/cw4-group/src/error.rs @@ -21,5 +21,5 @@ pub enum ContractError { Unauthorized {}, #[error("Message contained duplicate member: {member}")] - DuplicateMembers { member: String }, + DuplicateMember { member: String }, } diff --git a/contracts/cw4-group/src/helpers.rs b/contracts/cw4-group/src/helpers.rs index 10e3edf99..9611ed9d6 100644 --- a/contracts/cw4-group/src/helpers.rs +++ b/contracts/cw4-group/src/helpers.rs @@ -46,7 +46,7 @@ pub fn validate_unique_members(members: &mut [Member]) -> Result<(), ContractErr members.sort_by(|a, b| a.addr.cmp(&b.addr)); for (a, b) in members.iter().zip(members.iter().skip(1)) { if a.addr == b.addr { - return Err(ContractError::DuplicateMembers { + return Err(ContractError::DuplicateMember { member: a.addr.clone(), }); } diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index d18189d9c..9ed220523 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -90,7 +90,7 @@ fn duplicate_members_instantiation() { let err = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!( err, - ContractError::DuplicateMembers { + ContractError::DuplicateMember { member: USER1.to_string() } ); @@ -125,7 +125,7 @@ fn duplicate_members_execution() { assert_eq!( err, - ContractError::DuplicateMembers { + ContractError::DuplicateMember { member: USER3.to_string() } ); From 9bb42edc06da4c88e9977657201be130a6c8e44d Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 12 Oct 2022 20:35:16 +0200 Subject: [PATCH 509/631] cw4-group: remove unnecessary update --- contracts/cw4-group/src/contract.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 711b6b655..68bd654ae 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -56,12 +56,6 @@ pub fn create( let member_weight = Uint64::from(member.weight); total = total.checked_add(member_weight)?; let member_addr = deps.api.addr_validate(&member.addr)?; - MEMBERS.update(deps.storage, &member_addr, height, |v| -> StdResult { - match v { - Some(weight) => Ok(weight + member_weight.u64()), - None => Ok(member_weight.u64()), - } - })?; MEMBERS.save(deps.storage, &member_addr, &member_weight.u64(), height)?; } TOTAL.save(deps.storage, &total.u64(), height)?; From cef94c2054b809822e254e6d09545449b64ea795 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 15 Aug 2022 21:18:13 +0200 Subject: [PATCH 510/631] multi-test: WIP add staking and distribution modules --- packages/multi-test/src/app.rs | 22 ++-- packages/multi-test/src/lib.rs | 2 +- packages/multi-test/src/staking.rs | 172 ++++++++++++++++++++++++++++- 3 files changed, 184 insertions(+), 12 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 8227bff24..74b6aa78b 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -17,7 +17,9 @@ use crate::bank::{Bank, BankKeeper, BankSudo}; use crate::contracts::Contract; use crate::executor::{AppResponse, Executor}; use crate::module::{FailingModule, Module}; -use crate::staking::{Distribution, FailingDistribution, FailingStaking, Staking, StakingSudo}; +use crate::staking::{ + Distribution, FailingDistribution, FailingStaking, StakeKeeper, Staking, StakingSudo, +}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo}; @@ -44,7 +46,7 @@ pub struct App< Storage = MockStorage, Custom = FailingModule, Wasm = WasmKeeper, - Staking = FailingStaking, + Staking = StakeKeeper, Distr = FailingDistribution, > { router: Router, @@ -75,7 +77,7 @@ impl BasicApp { BankKeeper, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, >, &dyn Api, @@ -97,7 +99,7 @@ where BankKeeper, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, >, &dyn Api, @@ -159,7 +161,7 @@ pub type BasicAppBuilder = AppBuilder< MockStorage, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, >; @@ -182,7 +184,7 @@ impl Default MockStorage, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, > { @@ -198,7 +200,7 @@ impl MockStorage, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, > { @@ -211,7 +213,7 @@ impl bank: BankKeeper::new(), wasm: WasmKeeper::new(), custom: FailingModule::new(), - staking: FailingStaking::new(), + staking: StakeKeeper::new(), distribution: FailingDistribution::new(), } } @@ -224,7 +226,7 @@ impl MockStorage, FailingModule, WasmKeeper, - FailingStaking, + StakeKeeper, FailingDistribution, > where @@ -241,7 +243,7 @@ where bank: BankKeeper::new(), wasm: WasmKeeper::new(), custom: FailingModule::new(), - staking: FailingStaking::new(), + staking: StakeKeeper::new(), distribution: FailingDistribution::new(), } } diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 662db3bb6..4f54c991a 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -28,5 +28,5 @@ pub use crate::bank::{Bank, BankKeeper, BankSudo}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; pub use crate::module::{FailingModule, Module}; -pub use crate::staking::{FailingDistribution, FailingStaking, Staking, StakingSudo}; +pub use crate::staking::{FailingDistribution, FailingStaking, StakeKeeper, Staking, StakingSudo}; pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 20254a87e..973ce5b41 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -1,9 +1,23 @@ -use cosmwasm_std::{Decimal, DistributionMsg, Empty, StakingMsg, StakingQuery}; +use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; +use cosmwasm_std::{ + Addr, Api, Binary, BlockInfo, Coin, Decimal, DistributionMsg, Empty, Event, Querier, + StakingMsg, StakingQuery, Storage, DelegationResponse, FullDelegation, to_binary, coin, Uint128 +}; +use cosmwasm_storage::{prefixed, prefixed_read}; +use cw_storage_plus::Map; +use cw_utils::NativeBalance; + +use crate::app::CosmosRouter; +use crate::executor::AppResponse; use crate::module::FailingModule; use crate::Module; +const STAKES: Map<&Addr, NativeBalance> = Map::new("stakes"); + +pub const NAMESPACE_STAKING: &[u8] = b"staking"; + // We need to expand on this, but we will need this to properly test out staking #[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub enum StakingSudo { @@ -24,3 +38,159 @@ pub trait Distribution: Module; impl Distribution for FailingDistribution {} + +#[derive(Default)] +pub struct StakeKeeper {} + +impl StakeKeeper { + pub fn new() -> Self { + StakeKeeper {} + } + + pub fn init_balance( + &self, + storage: &mut dyn Storage, + account: &Addr, + amount: Vec, + ) -> AnyResult<()> { + let mut storage = prefixed(storage, NAMESPACE_STAKING); + self.set_balance(&mut storage, account, amount) + } + + fn get_stakes(&self, storage: &dyn Storage, account: &Addr) -> AnyResult> { + let val = STAKES.may_load(storage, account)?; + Ok(val.unwrap_or_default().into_vec()) + } + + fn set_balance( + &self, + storage: &mut dyn Storage, + account: &Addr, + amount: Vec, + ) -> AnyResult<()> { + let mut stake = NativeBalance(amount); + stake.normalize(); + STAKES.save(storage, account, &stake).map_err(Into::into) + } + + fn add_stake( + &self, + storage: &mut dyn Storage, + to_address: Addr, + amount: Vec, + ) -> AnyResult<()> { + let amount = self.normalize_amount(amount)?; + let b = self.get_stakes(storage, &to_address)?; + let b = NativeBalance(b) + NativeBalance(amount); + self.set_balance(storage, &to_address, b.into_vec()) + } + + fn remove_stake( + &self, + storage: &mut dyn Storage, + from_address: Addr, + amount: Vec, + ) -> AnyResult<()> { + let amount = self.normalize_amount(amount)?; + let a = self.get_stakes(storage, &from_address)?; + let a = (NativeBalance(a) - amount)?; + self.set_balance(storage, &from_address, a.into_vec()) + } + + /// Filters out all 0 value coins and returns an error if the resulting Vec is empty + fn normalize_amount(&self, amount: Vec) -> AnyResult> { + let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); + if res.is_empty() { + bail!("Cannot transfer empty coins amount") + } else { + Ok(res) + } + } +} + +impl Staking for StakeKeeper {} + +impl Module for StakeKeeper { + type ExecT = StakingMsg; + type QueryT = StakingQuery; + type SudoT = StakingSudo; + + fn execute( + &self, + _api: &dyn Api, + storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + sender: Addr, + msg: StakingMsg, + ) -> AnyResult { + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + match msg { + StakingMsg::Delegate { validator, amount } => { + let events = vec![Event::new("delegate") + .add_attribute("recipient", &validator) + .add_attribute("sender", &sender) + .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; + self.add_stake(&mut staking_storage, sender, vec![amount])?; + Ok(AppResponse { events, data: None }) + }, + StakingMsg::Undelegate { validator, amount } => { + let events = vec![Event::new("undelegate") + .add_attribute("from", &validator) + .add_attribute("to", &sender) + .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; + self.remove_stake(&mut staking_storage, sender, vec![amount])?; + Ok(AppResponse { events, data: None }) + } + m => bail!("Unsupported staking message: {:?}", m), + } + } + + fn sudo( + &self, + _api: &dyn Api, + _storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + msg: StakingSudo, + ) -> AnyResult { + match msg { + s => bail!("Unsupported staking sudo message: {:?}", s), + } + } + + fn query( + &self, + api: &dyn Api, + storage: &dyn Storage, + _querier: &dyn Querier, + _block: &BlockInfo, + request: StakingQuery, + ) -> AnyResult { + let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); + match request { + StakingQuery::Delegation { delegator, validator } => { + // for now validator is ignored, as I want to support only one validator + let delegator = api.addr_validate(&delegator)?; + let stakes = match self.get_stakes(&staking_storage, &delegator) { + Ok(stakes) => stakes[0].clone(), + Err(_) => { + let response = DelegationResponse { delegation: None }; + return Ok(to_binary(&response)?); + } + }; + // set fixed reward ratio 1:10 per delegated amoutn + let reward = coin((stakes.amount / Uint128::new(10)).u128(), stakes.denom.clone()); + let full_delegation_response = FullDelegation { + delegator, + validator, + amount: stakes, + can_redelegate: coin(0, "testcoin"), + accumulated_rewards: vec![reward], + }; + Ok(to_binary(&full_delegation_response)?) + } + q => bail!("Unsupported staking sudo message: {:?}", q), + } + } +} From 180d049daa706f0b66d6f71a2d66c39923083cbc Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Thu, 18 Aug 2022 15:41:01 +0200 Subject: [PATCH 511/631] multi-test: WIP add distribution module implementation --- packages/multi-test/src/staking.rs | 126 +++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 5 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 973ce5b41..0aac1ba81 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -2,8 +2,9 @@ use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; use cosmwasm_std::{ - Addr, Api, Binary, BlockInfo, Coin, Decimal, DistributionMsg, Empty, Event, Querier, - StakingMsg, StakingQuery, Storage, DelegationResponse, FullDelegation, to_binary, coin, Uint128 + coin, to_binary, Addr, Api, Binary, BlockInfo, Coin, Decimal, DelegationResponse, + DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, StakingQuery, Storage, + Uint128, }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::Map; @@ -133,7 +134,7 @@ impl Module for StakeKeeper { .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; self.add_stake(&mut staking_storage, sender, vec![amount])?; Ok(AppResponse { events, data: None }) - }, + } StakingMsg::Undelegate { validator, amount } => { let events = vec![Event::new("undelegate") .add_attribute("from", &validator) @@ -169,7 +170,10 @@ impl Module for StakeKeeper { ) -> AnyResult { let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); match request { - StakingQuery::Delegation { delegator, validator } => { + StakingQuery::Delegation { + delegator, + validator, + } => { // for now validator is ignored, as I want to support only one validator let delegator = api.addr_validate(&delegator)?; let stakes = match self.get_stakes(&staking_storage, &delegator) { @@ -180,7 +184,10 @@ impl Module for StakeKeeper { } }; // set fixed reward ratio 1:10 per delegated amoutn - let reward = coin((stakes.amount / Uint128::new(10)).u128(), stakes.denom.clone()); + let reward = coin( + (stakes.amount / Uint128::new(10)).u128(), + stakes.denom.clone(), + ); let full_delegation_response = FullDelegation { delegator, validator, @@ -194,3 +201,112 @@ impl Module for StakeKeeper { } } } + +#[derive(Default)] +pub struct DistributionKeeper {} + +impl DistributionKeeper { + pub fn new() -> Self { + DistributionKeeper {} + } + + fn get_stakes(&self, storage: &dyn Storage, account: &Addr) -> AnyResult> { + let val = STAKES.may_load(storage, account)?; + Ok(val.unwrap_or_default().into_vec()) + } + + fn set_balance( + &self, + storage: &mut dyn Storage, + account: &Addr, + amount: Vec, + ) -> AnyResult<()> { + let mut stake = NativeBalance(amount); + stake.normalize(); + STAKES.save(storage, account, &stake).map_err(Into::into) + } + + fn add_stake( + &self, + storage: &mut dyn Storage, + to_address: Addr, + amount: Vec, + ) -> AnyResult<()> { + let amount = self.normalize_amount(amount)?; + let b = self.get_stakes(storage, &to_address)?; + let b = NativeBalance(b) + NativeBalance(amount); + self.set_balance(storage, &to_address, b.into_vec()) + } + + /// Filters out all 0 value coins and returns an error if the resulting Vec is empty + fn normalize_amount(&self, amount: Vec) -> AnyResult> { + let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); + if res.is_empty() { + bail!("Cannot transfer empty coins amount") + } else { + Ok(res) + } + } +} + +impl Distribution for DistributionKeeper {} + +impl Module for DistributionKeeper { + type ExecT = DistributionMsg; + type QueryT = Empty; + type SudoT = Empty; + + fn execute( + &self, + _api: &dyn Api, + storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + sender: Addr, + msg: DistributionMsg, + ) -> AnyResult { + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + match msg { + // For now it ignores validator as I want to support only one + DistributionMsg::WithdrawDelegatorReward { validator } => { + let stakes = self.get_stakes(&staking_storage, &sender)?[0].clone(); + // set fixed reward ratio 1:10 per delegated amoutn + let reward = coin( + (stakes.amount / Uint128::new(10)).u128(), + stakes.denom.clone(), + ); + + let events = vec![Event::new("withdraw_delegator_reward") + .add_attribute("validator", &validator) + .add_attribute("sender", &sender) + .add_attribute("amount", format!("{}{}", reward.amount, reward.denom))]; + // add balance to sender + self.add_stake(&mut staking_storage, sender, vec![reward])?; + Ok(AppResponse { events, data: None }) + } + m => bail!("Unsupported distribution message: {:?}", m), + } + } + + fn sudo( + &self, + _api: &dyn Api, + _storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + _msg: Empty, + ) -> AnyResult { + bail!("Something went wrong - Distribution doesn't have sudo messages") + } + + fn query( + &self, + _api: &dyn Api, + _storage: &dyn Storage, + _querier: &dyn Querier, + _block: &BlockInfo, + _request: Empty, + ) -> AnyResult { + bail!("Something went wrong - Distribution doesn't have query messages") + } +} From e5318a6594042420cb77ec2fd8873af59b232f90 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Thu, 18 Aug 2022 15:46:35 +0200 Subject: [PATCH 512/631] multi-test: Replace FailingDistribution and FailingStaking with DistributionKeeper and StakeKeeper modules --- packages/multi-test/src/app.rs | 22 ++++++++++------------ packages/multi-test/src/lib.rs | 2 +- packages/multi-test/src/staking.rs | 18 ++---------------- packages/multi-test/src/wasm.rs | 10 +++++----- 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 74b6aa78b..18e498418 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -17,9 +17,7 @@ use crate::bank::{Bank, BankKeeper, BankSudo}; use crate::contracts::Contract; use crate::executor::{AppResponse, Executor}; use crate::module::{FailingModule, Module}; -use crate::staking::{ - Distribution, FailingDistribution, FailingStaking, StakeKeeper, Staking, StakingSudo, -}; +use crate::staking::{Distribution, DistributionKeeper, StakeKeeper, Staking, StakingSudo}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo}; @@ -47,7 +45,7 @@ pub struct App< Custom = FailingModule, Wasm = WasmKeeper, Staking = StakeKeeper, - Distr = FailingDistribution, + Distr = DistributionKeeper, > { router: Router, api: Api, @@ -78,7 +76,7 @@ impl BasicApp { FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, >, &dyn Api, &mut dyn Storage, @@ -100,7 +98,7 @@ where FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, >, &dyn Api, &mut dyn Storage, @@ -162,7 +160,7 @@ pub type BasicAppBuilder = AppBuilder< FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, >; /// Utility to build App in stages. If particular items wont be set, defaults would be used @@ -185,7 +183,7 @@ impl Default FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, > { fn default() -> Self { @@ -201,7 +199,7 @@ impl FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, > { /// Creates builder with default components working with empty exec and query messages. @@ -214,7 +212,7 @@ impl wasm: WasmKeeper::new(), custom: FailingModule::new(), staking: StakeKeeper::new(), - distribution: FailingDistribution::new(), + distribution: DistributionKeeper::new(), } } } @@ -227,7 +225,7 @@ impl FailingModule, WasmKeeper, StakeKeeper, - FailingDistribution, + DistributionKeeper, > where ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, @@ -244,7 +242,7 @@ where wasm: WasmKeeper::new(), custom: FailingModule::new(), staking: StakeKeeper::new(), - distribution: FailingDistribution::new(), + distribution: DistributionKeeper::new(), } } } diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 4f54c991a..572c72c87 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -28,5 +28,5 @@ pub use crate::bank::{Bank, BankKeeper, BankSudo}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; pub use crate::module::{FailingModule, Module}; -pub use crate::staking::{FailingDistribution, FailingStaking, StakeKeeper, Staking, StakingSudo}; +pub use crate::staking::{DistributionKeeper, StakeKeeper, Staking, StakingSudo}; pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 0aac1ba81..ea747caf3 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -12,7 +12,6 @@ use cw_utils::NativeBalance; use crate::app::CosmosRouter; use crate::executor::AppResponse; -use crate::module::FailingModule; use crate::Module; const STAKES: Map<&Addr, NativeBalance> = Map::new("stakes"); @@ -30,16 +29,8 @@ pub enum StakingSudo { pub trait Staking: Module {} -pub type FailingStaking = FailingModule; - -impl Staking for FailingStaking {} - pub trait Distribution: Module {} -pub type FailingDistribution = FailingModule; - -impl Distribution for FailingDistribution {} - #[derive(Default)] pub struct StakeKeeper {} @@ -155,9 +146,7 @@ impl Module for StakeKeeper { _block: &BlockInfo, msg: StakingSudo, ) -> AnyResult { - match msg { - s => bail!("Unsupported staking sudo message: {:?}", s), - } + bail!("Unsupported staking sudo message: {:?}", msg) } fn query( @@ -271,10 +260,7 @@ impl Module for DistributionKeeper { DistributionMsg::WithdrawDelegatorReward { validator } => { let stakes = self.get_stakes(&staking_storage, &sender)?[0].clone(); // set fixed reward ratio 1:10 per delegated amoutn - let reward = coin( - (stakes.amount / Uint128::new(10)).u128(), - stakes.denom.clone(), - ); + let reward = coin((stakes.amount / Uint128::new(10)).u128(), stakes.denom); let events = vec![Event::new("withdraw_delegator_reward") .add_attribute("validator", &validator) diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index f615cc0df..bb0490332 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -941,20 +941,20 @@ mod test { use crate::app::Router; use crate::bank::BankKeeper; use crate::module::FailingModule; + use crate::staking::{DistributionKeeper, StakeKeeper}; use crate::test_helpers::contracts::{caller, error, payout}; use crate::test_helpers::EmptyMsg; use crate::transactions::StorageTransaction; use super::*; - use crate::staking::{FailingDistribution, FailingStaking}; /// Type alias for default build `Router` to make its reference in typical scenario type BasicRouter = Router< BankKeeper, FailingModule, WasmKeeper, - FailingStaking, - FailingDistribution, + StakeKeeper, + DistributionKeeper, >; fn mock_router() -> BasicRouter { @@ -962,8 +962,8 @@ mod test { wasm: WasmKeeper::new(), bank: BankKeeper::new(), custom: FailingModule::new(), - staking: FailingStaking::new(), - distribution: FailingDistribution::new(), + staking: StakeKeeper::new(), + distribution: DistributionKeeper::new(), } } From 2666aa5a4b16e561daf7c3c09cde9a4225bc4c5f Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 19 Aug 2022 23:40:34 +0200 Subject: [PATCH 513/631] multi-test: Add Distribution to CustomMsg matcher --- packages/multi-test/src/contracts.rs | 1 + packages/multi-test/src/staking.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs index 68ef4c30b..b38cdc114 100644 --- a/packages/multi-test/src/contracts.rs +++ b/packages/multi-test/src/contracts.rs @@ -351,6 +351,7 @@ where CosmosMsg::Wasm(wasm) => CosmosMsg::Wasm(wasm), CosmosMsg::Bank(bank) => CosmosMsg::Bank(bank), CosmosMsg::Staking(staking) => CosmosMsg::Staking(staking), + CosmosMsg::Distribution(distribution) => CosmosMsg::Distribution(distribution), CosmosMsg::Custom(_) => unreachable!(), #[cfg(feature = "stargate")] CosmosMsg::Ibc(ibc) => CosmosMsg::Ibc(ibc), diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index ea747caf3..0d0de430d 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -177,14 +177,18 @@ impl Module for StakeKeeper { (stakes.amount / Uint128::new(10)).u128(), stakes.denom.clone(), ); - let full_delegation_response = FullDelegation { - delegator, - validator, - amount: stakes, - can_redelegate: coin(0, "testcoin"), - accumulated_rewards: vec![reward], + let full_delegation_response = DelegationResponse { + delegation: Some(FullDelegation { + delegator, + validator, + amount: stakes, + can_redelegate: coin(0, "testcoin"), + accumulated_rewards: vec![reward], + }), }; - Ok(to_binary(&full_delegation_response)?) + + let res = to_binary(&full_delegation_response)?; + Ok(res) } q => bail!("Unsupported staking sudo message: {:?}", q), } From ce4b4c7468bb68c4522937bb569f343f50a969bf Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Sun, 21 Aug 2022 13:27:25 +0200 Subject: [PATCH 514/631] multi-test: Fix bug by removing addition of stake at withdraw_rewards call --- packages/multi-test/src/staking.rs | 38 ++---------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 0d0de430d..8da4ce75f 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -207,39 +207,6 @@ impl DistributionKeeper { let val = STAKES.may_load(storage, account)?; Ok(val.unwrap_or_default().into_vec()) } - - fn set_balance( - &self, - storage: &mut dyn Storage, - account: &Addr, - amount: Vec, - ) -> AnyResult<()> { - let mut stake = NativeBalance(amount); - stake.normalize(); - STAKES.save(storage, account, &stake).map_err(Into::into) - } - - fn add_stake( - &self, - storage: &mut dyn Storage, - to_address: Addr, - amount: Vec, - ) -> AnyResult<()> { - let amount = self.normalize_amount(amount)?; - let b = self.get_stakes(storage, &to_address)?; - let b = NativeBalance(b) + NativeBalance(amount); - self.set_balance(storage, &to_address, b.into_vec()) - } - - /// Filters out all 0 value coins and returns an error if the resulting Vec is empty - fn normalize_amount(&self, amount: Vec) -> AnyResult> { - let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); - if res.is_empty() { - bail!("Cannot transfer empty coins amount") - } else { - Ok(res) - } - } } impl Distribution for DistributionKeeper {} @@ -258,7 +225,7 @@ impl Module for DistributionKeeper { sender: Addr, msg: DistributionMsg, ) -> AnyResult { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + let staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { // For now it ignores validator as I want to support only one DistributionMsg::WithdrawDelegatorReward { validator } => { @@ -270,8 +237,7 @@ impl Module for DistributionKeeper { .add_attribute("validator", &validator) .add_attribute("sender", &sender) .add_attribute("amount", format!("{}{}", reward.amount, reward.denom))]; - // add balance to sender - self.add_stake(&mut staking_storage, sender, vec![reward])?; + // TODO: add balance to sender by sending BankMsg transfer Ok(AppResponse { events, data: None }) } m => bail!("Unsupported distribution message: {:?}", m), From 9c1cdb89ba5bc5e7edf138bc2b639cc43834813e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 16 Sep 2022 11:02:00 +0200 Subject: [PATCH 515/631] Show how to call "root" on Bank module from Staking --- packages/multi-test/src/staking.rs | 69 ++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 8da4ce75f..b382d49b0 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -2,9 +2,9 @@ use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; use cosmwasm_std::{ - coin, to_binary, Addr, Api, Binary, BlockInfo, Coin, Decimal, DelegationResponse, - DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, StakingQuery, Storage, - Uint128, + coin, coins, to_binary, Addr, Api, BankMsg, Binary, BlockInfo, Coin, CustomQuery, Decimal, + DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, + StakingQuery, Storage, Uint128, }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::Map; @@ -12,7 +12,7 @@ use cw_utils::NativeBalance; use crate::app::CosmosRouter; use crate::executor::AppResponse; -use crate::Module; +use crate::{BankSudo, Module}; const STAKES: Map<&Addr, NativeBalance> = Map::new("stakes"); @@ -31,12 +31,16 @@ pub trait Staking: Module {} -#[derive(Default)] -pub struct StakeKeeper {} +pub struct StakeKeeper { + module_addr: Addr, +} impl StakeKeeper { pub fn new() -> Self { - StakeKeeper {} + StakeKeeper { + // define this better?? it is an account for everything held my the staking keeper + module_addr: Addr::unchecked("staking_module"), + } } pub fn init_balance( @@ -107,23 +111,36 @@ impl Module for StakeKeeper { type QueryT = StakingQuery; type SudoT = StakingSudo; - fn execute( + fn execute( &self, - _api: &dyn Api, + api: &dyn Api, storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, + router: &dyn CosmosRouter, + block: &BlockInfo, sender: Addr, msg: StakingMsg, ) -> AnyResult { let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { StakingMsg::Delegate { validator, amount } => { + // TODO: assert amount is the proper denom let events = vec![Event::new("delegate") .add_attribute("recipient", &validator) .add_attribute("sender", &sender) .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; - self.add_stake(&mut staking_storage, sender, vec![amount])?; + self.add_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + // move money from sender account to this module (note we can controller sender here) + router.execute( + api, + storage, + block, + sender, + BankMsg::Send { + to_address: self.module_addr.to_string(), + amount: vec![amount], + } + .into(), + )?; Ok(AppResponse { events, data: None }) } StakingMsg::Undelegate { validator, amount } => { @@ -131,7 +148,33 @@ impl Module for StakeKeeper { .add_attribute("from", &validator) .add_attribute("to", &sender) .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; - self.remove_stake(&mut staking_storage, sender, vec![amount])?; + self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + // move token from this module to sender account + // TODO: actually store this so it is released later after unbonding period + // but showing how to do the payback + router.execute( + api, + storage, + block, + self.module_addr.clone(), + BankMsg::Send { + to_address: sender.into_string(), + amount: vec![amount], + } + .into(), + )?; + + // NB: when you need more tokens for staking rewards you can do something like: + router.sudo( + api, + storage, + block, + BankSudo::Mint { + to_address: self.module_addr.to_string(), + amount: coins(123456000, "ucosm"), + } + .into(), + )?; Ok(AppResponse { events, data: None }) } m => bail!("Unsupported staking message: {:?}", m), From 415ea75742c641d1e88e8e54270eac0c2fdf4e8a Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 16:18:41 +0200 Subject: [PATCH 516/631] Change event signatures to match cosmos-sdk --- packages/multi-test/src/staking.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index b382d49b0..0fb51d7b4 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -124,10 +124,11 @@ impl Module for StakeKeeper { match msg { StakingMsg::Delegate { validator, amount } => { // TODO: assert amount is the proper denom + // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L251-L256 let events = vec![Event::new("delegate") - .add_attribute("recipient", &validator) - .add_attribute("sender", &sender) - .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; + .add_attribute("validator", &validator) + .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) + .add_attribute("new_shares", amount.amount.to_string())]; // TODO: calculate shares? self.add_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; // move money from sender account to this module (note we can controller sender here) router.execute( @@ -144,10 +145,11 @@ impl Module for StakeKeeper { Ok(AppResponse { events, data: None }) } StakingMsg::Undelegate { validator, amount } => { - let events = vec![Event::new("undelegate") - .add_attribute("from", &validator) - .add_attribute("to", &sender) - .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; + // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 + let events = vec![Event::new("unbond") + .add_attribute("validator", &validator) + .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) + .add_attribute("completion_time", "2022-09-27T14:00:00+00:00")]; // TODO: actual date? self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; // move token from this module to sender account // TODO: actually store this so it is released later after unbonding period From 95f28301256f9189638010ed0d56a11c1fdf3be7 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 16:19:58 +0200 Subject: [PATCH 517/631] Handle redelegation msg in StakeKeeper --- packages/multi-test/src/staking.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 0fb51d7b4..0799ae85b 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -179,6 +179,23 @@ impl Module for StakeKeeper { )?; Ok(AppResponse { events, data: None }) } + StakingMsg::Redelegate { + src_validator, + dst_validator, + amount, + } => { + // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L316-L322 + let events = vec![Event::new("redelegate") + .add_attribute("source_validator", &src_validator) + .add_attribute("destination_validator", &dst_validator) + .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; + + // this is not a noop, since there is validation regarding the amount + self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + self.add_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + + Ok(AppResponse { events, data: None }) + } m => bail!("Unsupported staking message: {:?}", m), } } From 947f96597d488c330be7e6b2f439ab912b194d02 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 27 Sep 2022 16:32:04 +0200 Subject: [PATCH 518/631] Remove unnecessary clones --- packages/multi-test/src/staking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 0799ae85b..97f973964 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -192,7 +192,7 @@ impl Module for StakeKeeper { // this is not a noop, since there is validation regarding the amount self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; - self.add_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + self.add_stake(&mut staking_storage, sender, vec![amount])?; Ok(AppResponse { events, data: None }) } From bd36ab1957f7fb547afae0fab87bc1432f6a1a45 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 4 Oct 2022 16:51:29 +0200 Subject: [PATCH 519/631] Add staking reward config and more staking queries --- packages/multi-test/src/staking.rs | 127 +++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 25 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 97f973964..47c854c09 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -2,12 +2,13 @@ use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; use cosmwasm_std::{ - coin, coins, to_binary, Addr, Api, BankMsg, Binary, BlockInfo, Coin, CustomQuery, Decimal, + coin, coins, from_slice, to_binary, Addr, AllDelegationsResponse, AllValidatorsResponse, Api, + BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, Decimal, Delegation, DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, - StakingQuery, Storage, Uint128, + StakingQuery, Storage, Validator, ValidatorResponse, }; use cosmwasm_storage::{prefixed, prefixed_read}; -use cw_storage_plus::Map; +use cw_storage_plus::{Item, Map}; use cw_utils::NativeBalance; use crate::app::CosmosRouter; @@ -15,6 +16,7 @@ use crate::executor::AppResponse; use crate::{BankSudo, Module}; const STAKES: Map<&Addr, NativeBalance> = Map::new("stakes"); +const REWARD_RATIO: Item = Item::new("reward_ratio"); pub const NAMESPACE_STAKING: &[u8] = b"staking"; @@ -25,6 +27,9 @@ pub enum StakingSudo { validator: String, percentage: Decimal, }, + UpdateRewardsRatio { + ratio: Decimal, + }, } pub trait Staking: Module {} @@ -33,13 +38,28 @@ pub trait Distribution: Module Self { + Self::new() + } } impl StakeKeeper { pub fn new() -> Self { StakeKeeper { - // define this better?? it is an account for everything held my the staking keeper + // define this better?? it is an account for everything held by the staking keeper module_addr: Addr::unchecked("staking_module"), + validator: Validator { + address: "testvaloper1".to_string(), + commission: Decimal::percent(10), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }, + bonded_denom: "TOKEN".to_string(), } } @@ -53,6 +73,28 @@ impl StakeKeeper { self.set_balance(&mut storage, account, amount) } + pub fn set_reward_ratio(&self, storage: &mut dyn Storage, value: &Decimal) -> AnyResult<()> { + let mut storage = prefixed(storage, NAMESPACE_STAKING); + REWARD_RATIO.save(&mut storage, value).map_err(Into::into) + } + + /// Calculates the staking reward for the given stake based on the fixed ratio set using + /// `set_reward_ratio` + fn calculate_rewards(&self, storage: &dyn Storage, stake: &Coin) -> AnyResult { + let reward_radio = self.get_reward_ratio(storage)?; + Ok(coin( + (stake.amount * reward_radio).u128(), + stake.denom.clone(), + )) + } + + /// Returns the set reward ratio, or `0.1` if none was set + fn get_reward_ratio(&self, storage: &dyn Storage) -> AnyResult { + let ratio = REWARD_RATIO.may_load(storage)?; + + Ok(ratio.unwrap_or_else(|| Decimal::from_ratio(1u128, 10u128))) + } + fn get_stakes(&self, storage: &dyn Storage, account: &Addr) -> AnyResult> { let val = STAKES.may_load(storage, account)?; Ok(val.unwrap_or_default().into_vec()) @@ -203,12 +245,19 @@ impl Module for StakeKeeper { fn sudo( &self, _api: &dyn Api, - _storage: &mut dyn Storage, + storage: &mut dyn Storage, _router: &dyn CosmosRouter, _block: &BlockInfo, msg: StakingSudo, ) -> AnyResult { - bail!("Unsupported staking sudo message: {:?}", msg) + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + match msg { + StakingSudo::Slash { .. } => todo!("slash validator"), + StakingSudo::UpdateRewardsRatio { ratio } => { + self.set_reward_ratio(&mut staking_storage, &ratio)?; + Ok(AppResponse::default()) + } + } } fn query( @@ -221,11 +270,30 @@ impl Module for StakeKeeper { ) -> AnyResult { let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); match request { + StakingQuery::BondedDenom {} => Ok(to_binary(&BondedDenomResponse { + denom: self.bonded_denom.clone(), + })?), + StakingQuery::AllDelegations { delegator } => { + let delegator = api.addr_validate(&delegator)?; + let stakes = self.get_stakes(&staking_storage, &delegator)?; + Ok(to_binary(&AllDelegationsResponse { + delegations: vec![Delegation { + delegator, + validator: self.validator.address.clone(), + amount: stakes + .get(0) + .cloned() + .unwrap_or_else(|| coin(0, &self.bonded_denom)), + }], + })?) + } StakingQuery::Delegation { delegator, validator, } => { - // for now validator is ignored, as I want to support only one validator + if validator != self.validator.address { + bail!("non-existent validator {}", validator); + } let delegator = api.addr_validate(&delegator)?; let stakes = match self.get_stakes(&staking_storage, &delegator) { Ok(stakes) => stakes[0].clone(), @@ -234,11 +302,8 @@ impl Module for StakeKeeper { return Ok(to_binary(&response)?); } }; - // set fixed reward ratio 1:10 per delegated amoutn - let reward = coin( - (stakes.amount / Uint128::new(10)).u128(), - stakes.denom.clone(), - ); + // calculate rewards using fixed ratio + let reward = self.calculate_rewards(&staking_storage, &stakes)?; let full_delegation_response = DelegationResponse { delegation: Some(FullDelegation { delegator, @@ -252,6 +317,16 @@ impl Module for StakeKeeper { let res = to_binary(&full_delegation_response)?; Ok(res) } + StakingQuery::AllValidators {} => Ok(to_binary(&AllValidatorsResponse { + validators: vec![self.validator.clone()], + })?), + StakingQuery::Validator { address } => Ok(to_binary(&ValidatorResponse { + validator: if self.validator.address == address { + Some(self.validator.clone()) + } else { + None + }, + })?), q => bail!("Unsupported staking sudo message: {:?}", q), } } @@ -264,11 +339,6 @@ impl DistributionKeeper { pub fn new() -> Self { DistributionKeeper {} } - - fn get_stakes(&self, storage: &dyn Storage, account: &Addr) -> AnyResult> { - let val = STAKES.may_load(storage, account)?; - Ok(val.unwrap_or_default().into_vec()) - } } impl Distribution for DistributionKeeper {} @@ -278,22 +348,29 @@ impl Module for DistributionKeeper { type QueryT = Empty; type SudoT = Empty; - fn execute( + fn execute( &self, - _api: &dyn Api, + api: &dyn Api, storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, + router: &dyn CosmosRouter, + block: &BlockInfo, sender: Addr, msg: DistributionMsg, ) -> AnyResult { - let staking_storage = prefixed(storage, NAMESPACE_STAKING); + // let staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { // For now it ignores validator as I want to support only one DistributionMsg::WithdrawDelegatorReward { validator } => { - let stakes = self.get_stakes(&staking_storage, &sender)?[0].clone(); - // set fixed reward ratio 1:10 per delegated amoutn - let reward = coin((stakes.amount / Uint128::new(10)).u128(), stakes.denom); + let response: DelegationResponse = from_slice(&router.query( + api, + storage, + block, + cosmwasm_std::QueryRequest::Staking(StakingQuery::Delegation { + delegator: sender.to_string(), + validator: validator.clone(), + }), + )?)?; + let reward = &response.delegation.unwrap().accumulated_rewards[0]; let events = vec![Event::new("withdraw_delegator_reward") .add_attribute("validator", &validator) From d0030c9786cb4646f1c4122453828997c6f568f3 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 5 Oct 2022 17:30:48 +0200 Subject: [PATCH 520/631] Add multiple validators and slashing --- packages/multi-test/src/staking.rs | 549 ++++++++++++++++++++++++----- 1 file changed, 461 insertions(+), 88 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 47c854c09..199341744 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -1,22 +1,82 @@ -use anyhow::{bail, Result as AnyResult}; +use std::collections::{BTreeSet, VecDeque}; + +use anyhow::{anyhow, bail, Result as AnyResult}; use schemars::JsonSchema; use cosmwasm_std::{ - coin, coins, from_slice, to_binary, Addr, AllDelegationsResponse, AllValidatorsResponse, Api, - BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, Decimal, Delegation, - DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, - StakingQuery, Storage, Validator, ValidatorResponse, + coin, coins, ensure, ensure_eq, from_slice, to_binary, Addr, AllDelegationsResponse, + AllValidatorsResponse, Api, BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, + Decimal, Delegation, DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, + Querier, StakingMsg, StakingQuery, Storage, Uint128, Validator, ValidatorResponse, }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::{Item, Map}; -use cw_utils::NativeBalance; +use serde::{Deserialize, Serialize}; use crate::app::CosmosRouter; use crate::executor::AppResponse; use crate::{BankSudo, Module}; -const STAKES: Map<&Addr, NativeBalance> = Map::new("stakes"); -const REWARD_RATIO: Item = Item::new("reward_ratio"); +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +struct StakeInfo { + /// The block height when this stake was last edited. This is needed for slashing + height: u64, + + /// The number of shares of this validator the staker has + shares: Decimal, +} + +impl StakeInfo { + /// The stake of this delegator. Make sure to pass the correct validator in + pub fn stake(&self, validator: &ValidatorInfo) -> Uint128 { + self.shares / validator.total_shares * validator.stake + } +} +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +struct ValidatorInfo { + /// The stakers that have staked with this validator + stakers: BTreeSet, + /// The whole stake of all stakers + stake: Uint128, + /// The block height when this validator was last edited. This is needed for rewards calculation + height: u64, + /// The total number of shares this validator has issued, only used internally for calculating rewards + total_shares: Decimal, + /// The number of available rewards. This is updated whenever a + available_rewards: Decimal, +} + +impl ValidatorInfo { + pub fn new(block_height: u64) -> Self { + Self { + stakers: BTreeSet::new(), + stake: Uint128::zero(), + height: block_height, + total_shares: Decimal::zero(), + available_rewards: Decimal::zero(), + } + } + /// Returns the amount of shares a delegator gets for staking the given amount of tokens (bonded_denom) at this point in time. + /// This should usually be `1:1` unless the delegator was slashed. + pub fn shares_for(&self, stake: Uint128) -> Decimal { + if self.stake.is_zero() { + // first staker always gets 1:1 + Decimal::one() + } else { + Decimal::from_ratio(stake, 1u128) * self.total_shares + / Decimal::from_ratio(self.stake, 1u128) + } + } +} + +const STAKES: Map<(&Addr, &Addr), StakeInfo> = Map::new("stakes"); +const VALIDATOR_MAP: Map<&Addr, Validator> = Map::new("validator_map"); +/// Additional vec of validators, in case the `iterator` feature is disabled +const VALIDATORS: Item> = Item::new("validators"); +/// Contains additional info for each validator +const VALIDATOR_INFO: Map<&Addr, ValidatorInfo> = Map::new("validator_info"); +// TODO: replace with `Deque` +// const UNBONDING_QUEUE: Item> = Item::new("unbonding_queue"); pub const NAMESPACE_STAKING: &[u8] = b"staking"; @@ -27,9 +87,9 @@ pub enum StakingSudo { validator: String, percentage: Decimal, }, - UpdateRewardsRatio { - ratio: Decimal, - }, + /// Causes the unbonding queue to be processed. + /// This needs to be triggered manually, since there is no good place to do this right now + ProcessQueue {}, } pub trait Staking: Module {} @@ -38,8 +98,9 @@ pub trait Distribution: Module, + validator: &Addr, + amount: Coin, ) -> AnyResult<()> { let mut storage = prefixed(storage, NAMESPACE_STAKING); - self.set_balance(&mut storage, account, amount) + + self.add_stake(&mut storage, block, account, validator, amount) } - pub fn set_reward_ratio(&self, storage: &mut dyn Storage, value: &Decimal) -> AnyResult<()> { + /// Add a new validator available for staking + pub fn add_validator( + &self, + api: &dyn Api, + storage: &mut dyn Storage, + block: &BlockInfo, + validator: Validator, + ) -> AnyResult<()> { let mut storage = prefixed(storage, NAMESPACE_STAKING); - REWARD_RATIO.save(&mut storage, value).map_err(Into::into) + let val_addr = api.addr_validate(&validator.address)?; + if VALIDATOR_MAP.may_load(&storage, &val_addr)?.is_some() { + bail!( + "Cannot add validator {}, since a validator with that address already exists", + val_addr + ); + } + + VALIDATOR_MAP.save(&mut storage, &val_addr, &validator)?; + let mut vec = VALIDATORS.may_load(&storage)?.unwrap_or_default(); + vec.push(validator); + VALIDATORS.save(&mut storage, &vec)?; + VALIDATOR_INFO.save(&mut storage, &val_addr, &ValidatorInfo::new(block.height))?; + Ok(()) } /// Calculates the staking reward for the given stake based on the fixed ratio set using /// `set_reward_ratio` - fn calculate_rewards(&self, storage: &dyn Storage, stake: &Coin) -> AnyResult { - let reward_radio = self.get_reward_ratio(storage)?; - Ok(coin( - (stake.amount * reward_radio).u128(), - stake.denom.clone(), - )) + fn calculate_rewards(&self, storage: &dyn Storage, stake: Uint128) -> AnyResult { + todo!("calculate rewards"); } - /// Returns the set reward ratio, or `0.1` if none was set - fn get_reward_ratio(&self, storage: &dyn Storage) -> AnyResult { - let ratio = REWARD_RATIO.may_load(storage)?; - - Ok(ratio.unwrap_or_else(|| Decimal::from_ratio(1u128, 10u128))) + /// Returns the single validator with the given address (or `None` if there is no such validator) + fn get_validator(&self, storage: &dyn Storage, address: &Addr) -> AnyResult> { + Ok(VALIDATOR_MAP.may_load(storage, address)?) } - fn get_stakes(&self, storage: &dyn Storage, account: &Addr) -> AnyResult> { - let val = STAKES.may_load(storage, account)?; - Ok(val.unwrap_or_default().into_vec()) + /// Returns all available validators + fn get_validators(&self, storage: &dyn Storage) -> AnyResult> { + Ok(VALIDATORS.may_load(storage)?.unwrap_or_default()) } - fn set_balance( + fn get_stake( &self, - storage: &mut dyn Storage, + storage: &dyn Storage, account: &Addr, - amount: Vec, - ) -> AnyResult<()> { - let mut stake = NativeBalance(amount); - stake.normalize(); - STAKES.save(storage, account, &stake).map_err(Into::into) + validator: &Addr, + ) -> AnyResult { + let val = STAKES.may_load(storage, (account, validator))?; + let validator_info = VALIDATOR_INFO.may_load(storage, validator)?; + Ok(val + .zip(validator_info) + .map(|(s, validator_info)| s.stake(&validator_info)) + .unwrap_or_default()) } fn add_stake( &self, storage: &mut dyn Storage, - to_address: Addr, - amount: Vec, + block: &BlockInfo, + to_address: &Addr, + validator: &Addr, + amount: Coin, ) -> AnyResult<()> { - let amount = self.normalize_amount(amount)?; - let b = self.get_stakes(storage, &to_address)?; - let b = NativeBalance(b) + NativeBalance(amount); - self.set_balance(storage, &to_address, b.into_vec()) + self.validate_denom(&amount)?; + self.validate_nonzero(&amount)?; + self.update_stake(storage, block, to_address, validator, amount.amount, false) } fn remove_stake( &self, storage: &mut dyn Storage, - from_address: Addr, - amount: Vec, + block: &BlockInfo, + from_address: &Addr, + validator: &Addr, + amount: Coin, + ) -> AnyResult<()> { + self.validate_denom(&amount)?; + self.validate_nonzero(&amount)?; + self.update_stake(storage, block, from_address, validator, amount.amount, true) + } + + fn update_stake( + &self, + storage: &mut dyn Storage, + block: &BlockInfo, + delegator: &Addr, + validator: &Addr, + amount: impl Into, + sub: bool, + ) -> AnyResult<()> { + let amount = amount.into(); + + let mut validator_info = VALIDATOR_INFO + .may_load(storage, validator)? + .unwrap_or_else(|| ValidatorInfo::new(block.height)); + let mut stake_info = STAKES + .may_load(storage, (delegator, validator))? + .unwrap_or_else(|| StakeInfo { + height: block.height, + shares: Decimal::zero(), + }); + + // TODO: update rewards and validator_info.height + + if sub { + // remove the corresponding amount of shares + let shares = validator_info.shares_for(amount); + stake_info.shares -= shares; + + validator_info.stake = validator_info.stake.checked_sub(amount)?; + validator_info.total_shares -= shares; + } else { + let new_shares = validator_info.shares_for(amount); + stake_info.shares += new_shares; + + validator_info.stake = validator_info.stake.checked_add(amount)?; + validator_info.total_shares += new_shares; + } + + // save updated values + if stake_info.shares.is_zero() { + // no more stake, so remove + STAKES.remove(storage, (delegator, validator)); + validator_info.stakers.remove(delegator); + } else { + STAKES.save(storage, (delegator, validator), &stake_info)?; + validator_info.stakers.insert(delegator.clone()); + } + // save updated validator info + VALIDATOR_INFO.save(storage, validator, &validator_info)?; + + Ok(()) + } + + fn slash( + &self, + storage: &mut dyn Storage, + validator: &Addr, + percentage: Decimal, ) -> AnyResult<()> { - let amount = self.normalize_amount(amount)?; - let a = self.get_stakes(storage, &from_address)?; - let a = (NativeBalance(a) - amount)?; - self.set_balance(storage, &from_address, a.into_vec()) + let mut validator_info = VALIDATOR_INFO + .may_load(storage, validator)? + .ok_or_else(|| anyhow!("validator not found"))?; + + // TODO: handle rewards? Either update them before slashing or set them to zero, depending on the slashing logic + + let remaining_percentage = Decimal::one() - percentage; + validator_info.stake = validator_info.stake * remaining_percentage; + + // if the stake is completely gone, we clear all stakers and reinitialize the validator + if validator_info.stake.is_zero() { + // need to remove all stakes + for delegator in validator_info.stakers.iter() { + STAKES.remove(storage, (delegator, validator)); + } + validator_info.stakers.clear(); + validator_info.total_shares = Decimal::zero(); + } + VALIDATOR_INFO.save(storage, validator, &validator_info)?; + Ok(()) + } + + fn process_queue(&self, storage: &mut dyn Storage) -> AnyResult<()> { + // let mut queue = UNBONDING_QUEUE.may_load(storage)?.unwrap_or_default(); + + // while queue.front().is_some() { + // let Some((delegator, info)) = queue.pop_front(); + // } + // Ok(()) + + todo!("process queue") } /// Filters out all 0 value coins and returns an error if the resulting Vec is empty @@ -144,6 +314,31 @@ impl StakeKeeper { Ok(res) } } + + fn validate_nonzero(&self, amount: &Coin) -> AnyResult<()> { + ensure!(!amount.amount.is_zero(), anyhow!("cannot delegate 0 coins")); + Ok(()) + } + + // Asserts that the given coin has the proper denominator + fn validate_denom(&self, amount: &Coin) -> AnyResult<()> { + ensure_eq!( + amount.denom, + self.bonded_denom, + anyhow!( + "cannot delegate coins of denominator {}, only of {}", + amount.denom, + self.bonded_denom + ) + ); + Ok(()) + } + + // Asserts that the given coin has the proper denominator + fn validate_percentage(&self, percentage: Decimal) -> AnyResult<()> { + ensure!(percentage <= Decimal::one(), anyhow!("expected percentage")); + Ok(()) + } } impl Staking for StakeKeeper {} @@ -165,13 +360,20 @@ impl Module for StakeKeeper { let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { StakingMsg::Delegate { validator, amount } => { - // TODO: assert amount is the proper denom + let validator = api.addr_validate(&validator)?; + // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L251-L256 let events = vec![Event::new("delegate") .add_attribute("validator", &validator) .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) .add_attribute("new_shares", amount.amount.to_string())]; // TODO: calculate shares? - self.add_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + self.add_stake( + &mut staking_storage, + block, + &sender, + &validator, + amount.clone(), + )?; // move money from sender account to this module (note we can controller sender here) router.execute( api, @@ -187,12 +389,20 @@ impl Module for StakeKeeper { Ok(AppResponse { events, data: None }) } StakingMsg::Undelegate { validator, amount } => { + let validator = api.addr_validate(&validator)?; + // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 let events = vec![Event::new("unbond") .add_attribute("validator", &validator) .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) .add_attribute("completion_time", "2022-09-27T14:00:00+00:00")]; // TODO: actual date? - self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; + self.remove_stake( + &mut staking_storage, + block, + &sender, + &validator, + amount.clone(), + )?; // move token from this module to sender account // TODO: actually store this so it is released later after unbonding period // but showing how to do the payback @@ -226,15 +436,22 @@ impl Module for StakeKeeper { dst_validator, amount, } => { + let src_validator = api.addr_validate(&src_validator)?; + let dst_validator = api.addr_validate(&dst_validator)?; // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L316-L322 let events = vec![Event::new("redelegate") .add_attribute("source_validator", &src_validator) .add_attribute("destination_validator", &dst_validator) .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; - // this is not a noop, since there is validation regarding the amount - self.remove_stake(&mut staking_storage, sender.clone(), vec![amount.clone()])?; - self.add_stake(&mut staking_storage, sender, vec![amount])?; + self.remove_stake( + &mut staking_storage, + block, + &sender, + &src_validator, + amount.clone(), + )?; + self.add_stake(&mut staking_storage, block, &sender, &dst_validator, amount)?; Ok(AppResponse { events, data: None }) } @@ -244,7 +461,7 @@ impl Module for StakeKeeper { fn sudo( &self, - _api: &dyn Api, + api: &dyn Api, storage: &mut dyn Storage, _router: &dyn CosmosRouter, _block: &BlockInfo, @@ -252,9 +469,19 @@ impl Module for StakeKeeper { ) -> AnyResult { let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { - StakingSudo::Slash { .. } => todo!("slash validator"), - StakingSudo::UpdateRewardsRatio { ratio } => { - self.set_reward_ratio(&mut staking_storage, &ratio)?; + StakingSudo::Slash { + validator, + percentage, + } => { + let validator = api.addr_validate(&validator)?; + self.validate_percentage(percentage)?; + + self.slash(&mut staking_storage, &validator, percentage)?; + + Ok(AppResponse::default()) + } + StakingSudo::ProcessQueue {} => { + self.process_queue(&mut staking_storage)?; Ok(AppResponse::default()) } } @@ -275,40 +502,52 @@ impl Module for StakeKeeper { })?), StakingQuery::AllDelegations { delegator } => { let delegator = api.addr_validate(&delegator)?; - let stakes = self.get_stakes(&staking_storage, &delegator)?; - Ok(to_binary(&AllDelegationsResponse { - delegations: vec![Delegation { - delegator, - validator: self.validator.address.clone(), - amount: stakes - .get(0) - .cloned() - .unwrap_or_else(|| coin(0, &self.bonded_denom)), - }], - })?) + let validators = self.get_validators(&staking_storage)?; + + let res: AnyResult> = validators + .into_iter() + .map(|validator| { + let delegator = delegator.clone(); + let amount = self.get_stake( + &staking_storage, + &delegator, + &Addr::unchecked(&validator.address), + )?; + + Ok(Delegation { + delegator, + validator: validator.address, + amount: coin(amount.u128(), &self.bonded_denom), + }) + }) + .collect(); + + Ok(to_binary(&AllDelegationsResponse { delegations: res? })?) } StakingQuery::Delegation { delegator, validator, } => { - if validator != self.validator.address { + let validator_addr = Addr::unchecked(&validator); + let validator_obj = self.get_validator(storage, &validator_addr)?; + if validator_obj.is_none() { bail!("non-existent validator {}", validator); } let delegator = api.addr_validate(&delegator)?; - let stakes = match self.get_stakes(&staking_storage, &delegator) { - Ok(stakes) => stakes[0].clone(), + let stakes = match self.get_stake(&staking_storage, &delegator, &validator_addr) { + Ok(stakes) => stakes, Err(_) => { let response = DelegationResponse { delegation: None }; return Ok(to_binary(&response)?); } }; // calculate rewards using fixed ratio - let reward = self.calculate_rewards(&staking_storage, &stakes)?; + let reward = self.calculate_rewards(&staking_storage, stakes)?; let full_delegation_response = DelegationResponse { delegation: Some(FullDelegation { delegator, validator, - amount: stakes, + amount: coin(stakes.u128(), &self.bonded_denom), can_redelegate: coin(0, "testcoin"), accumulated_rewards: vec![reward], }), @@ -318,14 +557,10 @@ impl Module for StakeKeeper { Ok(res) } StakingQuery::AllValidators {} => Ok(to_binary(&AllValidatorsResponse { - validators: vec![self.validator.clone()], + validators: self.get_validators(&staking_storage)?, })?), StakingQuery::Validator { address } => Ok(to_binary(&ValidatorResponse { - validator: if self.validator.address == address { - Some(self.validator.clone()) - } else { - None - }, + validator: self.get_validator(&staking_storage, &Addr::unchecked(address))?, })?), q => bail!("Unsupported staking sudo message: {:?}", q), } @@ -405,3 +640,141 @@ impl Module for DistributionKeeper { bail!("Something went wrong - Distribution doesn't have query messages") } } + +#[cfg(test)] +mod test { + use crate::app::MockRouter; + + use super::*; + + use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; + + #[test] + fn add_get_validators() { + let api = MockApi::default(); + let mut store = MockStorage::new(); + let stake = StakeKeeper::new(); + let block = mock_env().block; + + // add validator + let valoper1 = Validator { + address: "testvaloper1".to_string(), + commission: Decimal::percent(10), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }; + stake + .add_validator(&api, &mut store, &block, valoper1.clone()) + .unwrap(); + + // get it + let staking_storage = prefixed_read(&store, NAMESPACE_STAKING); + let val = stake + .get_validator( + &staking_storage, + &api.addr_validate("testvaloper1").unwrap(), + ) + .unwrap() + .unwrap(); + assert_eq!(val, valoper1); + + // try to add with same address + let valoper1_fake = Validator { + address: "testvaloper1".to_string(), + commission: Decimal::percent(1), + max_commission: Decimal::percent(10), + max_change_rate: Decimal::percent(100), + }; + stake + .add_validator(&api, &mut store, &block, valoper1_fake) + .unwrap_err(); + + // should still be original value + let staking_storage = prefixed_read(&store, NAMESPACE_STAKING); + let val = stake + .get_validator( + &staking_storage, + &api.addr_validate("testvaloper1").unwrap(), + ) + .unwrap() + .unwrap(); + assert_eq!(val, valoper1); + } + + #[test] + fn validator_slashing() { + let api = MockApi::default(); + let router = MockRouter::default(); + let mut store = MockStorage::new(); + let stake = StakeKeeper::new(); + let block = mock_env().block; + + let delegator = Addr::unchecked("delegator"); + let validator = api.addr_validate("testvaloper1").unwrap(); + + // add validator + let valoper1 = Validator { + address: "testvaloper1".to_string(), + commission: Decimal::percent(10), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }; + stake + .add_validator(&api, &mut store, &block, valoper1) + .unwrap(); + + // stake 100 tokens + let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + stake + .add_stake( + &mut staking_storage, + &block, + &delegator, + &validator, + coin(100, "TOKEN"), + ) + .unwrap(); + + // slash 50% + stake + .sudo( + &api, + &mut store, + &router, + &block, + StakingSudo::Slash { + validator: "testvaloper1".to_string(), + percentage: Decimal::percent(50), + }, + ) + .unwrap(); + + // check stake + let staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + let stake_left = stake + .get_stake(&staking_storage, &delegator, &validator) + .unwrap(); + assert_eq!(stake_left.u128(), 50, "should have slashed 50%"); + + // slash all + stake + .sudo( + &api, + &mut store, + &router, + &block, + StakingSudo::Slash { + validator: "testvaloper1".to_string(), + percentage: Decimal::percent(100), + }, + ) + .unwrap(); + + // check stake + let staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + let stake_left = stake + .get_stake(&staking_storage, &delegator, &validator) + .unwrap(); + assert_eq!(stake_left.u128(), 0, "should have slashed whole stake"); + } +} From 8b11c7c394dd691764a8ffd6008239970c435e79 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 5 Oct 2022 17:50:15 +0200 Subject: [PATCH 521/631] Process unbonding queue --- packages/multi-test/src/staking.rs | 95 ++++++++++++++++-------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 199341744..2251663cc 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -7,7 +7,7 @@ use cosmwasm_std::{ coin, coins, ensure, ensure_eq, from_slice, to_binary, Addr, AllDelegationsResponse, AllValidatorsResponse, Api, BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, Decimal, Delegation, DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, - Querier, StakingMsg, StakingQuery, Storage, Uint128, Validator, ValidatorResponse, + Querier, StakingMsg, StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::{Item, Map}; @@ -76,7 +76,7 @@ const VALIDATORS: Item> = Item::new("validators"); /// Contains additional info for each validator const VALIDATOR_INFO: Map<&Addr, ValidatorInfo> = Map::new("validator_info"); // TODO: replace with `Deque` -// const UNBONDING_QUEUE: Item> = Item::new("unbonding_queue"); +const UNBONDING_QUEUE: Item> = Item::new("unbonding_queue"); pub const NAMESPACE_STAKING: &[u8] = b"staking"; @@ -294,17 +294,6 @@ impl StakeKeeper { Ok(()) } - fn process_queue(&self, storage: &mut dyn Storage) -> AnyResult<()> { - // let mut queue = UNBONDING_QUEUE.may_load(storage)?.unwrap_or_default(); - - // while queue.front().is_some() { - // let Some((delegator, info)) = queue.pop_front(); - // } - // Ok(()) - - todo!("process queue") - } - /// Filters out all 0 value coins and returns an error if the resulting Vec is empty fn normalize_amount(&self, amount: Vec) -> AnyResult> { let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); @@ -390,6 +379,8 @@ impl Module for StakeKeeper { } StakingMsg::Undelegate { validator, amount } => { let validator = api.addr_validate(&validator)?; + self.validate_denom(&amount)?; + self.validate_nonzero(&amount)?; // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 let events = vec![Event::new("unbond") @@ -403,32 +394,27 @@ impl Module for StakeKeeper { &validator, amount.clone(), )?; - // move token from this module to sender account - // TODO: actually store this so it is released later after unbonding period - // but showing how to do the payback - router.execute( - api, - storage, - block, - self.module_addr.clone(), - BankMsg::Send { - to_address: sender.into_string(), - amount: vec![amount], - } - .into(), - )?; - - // NB: when you need more tokens for staking rewards you can do something like: - router.sudo( - api, - storage, - block, - BankSudo::Mint { - to_address: self.module_addr.to_string(), - amount: coins(123456000, "ucosm"), - } - .into(), - )?; + // add tokens to unbonding queue + let mut queue = UNBONDING_QUEUE + .may_load(&staking_storage)? + .unwrap_or_default(); + queue.push_back(( + sender.clone(), + block.time.plus_seconds(self.unbonding_time), + amount.amount.u128(), + )); + + // // NB: when you need more tokens for staking rewards you can do something like: + // router.sudo( + // api, + // storage, + // block, + // BankSudo::Mint { + // to_address: self.module_addr.to_string(), + // amount: coins(123456000, "ucosm"), + // } + // .into(), + // )?; Ok(AppResponse { events, data: None }) } StakingMsg::Redelegate { @@ -459,12 +445,12 @@ impl Module for StakeKeeper { } } - fn sudo( + fn sudo( &self, api: &dyn Api, storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, + router: &dyn CosmosRouter, + block: &BlockInfo, msg: StakingSudo, ) -> AnyResult { let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); @@ -481,7 +467,30 @@ impl Module for StakeKeeper { Ok(AppResponse::default()) } StakingSudo::ProcessQueue {} => { - self.process_queue(&mut staking_storage)?; + let mut queue = UNBONDING_QUEUE.may_load(storage)?.unwrap_or_default(); + + loop { + match queue.front() { + // assuming the queue is sorted by payout_at + Some((_, payout_at, _)) if payout_at <= &block.time => { + // remove from queue + let (delegator, _, amount) = queue.pop_front().unwrap(); + + router.execute( + api, + storage, + block, + self.module_addr.clone(), + BankMsg::Send { + to_address: delegator.into_string(), + amount: vec![coin(amount, &self.bonded_denom)], + } + .into(), + )?; + } + _ => break, + } + } Ok(AppResponse::default()) } } From 294f4a24fd7de0ee35cd80195206f6d818151613 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 6 Oct 2022 14:22:11 +0200 Subject: [PATCH 522/631] Add (buggy) rewards calculation --- packages/multi-test/src/staking.rs | 657 +++++++++++++++++++++++------ 1 file changed, 530 insertions(+), 127 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 2251663cc..4cc97628c 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -4,10 +4,10 @@ use anyhow::{anyhow, bail, Result as AnyResult}; use schemars::JsonSchema; use cosmwasm_std::{ - coin, coins, ensure, ensure_eq, from_slice, to_binary, Addr, AllDelegationsResponse, - AllValidatorsResponse, Api, BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, - Decimal, Delegation, DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, - Querier, StakingMsg, StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, + coin, ensure, ensure_eq, to_binary, Addr, AllDelegationsResponse, AllValidatorsResponse, Api, + BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, Decimal, Delegation, + DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, + StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, }; use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::{Item, Map}; @@ -17,43 +17,58 @@ use crate::app::CosmosRouter; use crate::executor::AppResponse; use crate::{BankSudo, Module}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -struct StakeInfo { - /// The block height when this stake was last edited. This is needed for slashing - height: u64, - - /// The number of shares of this validator the staker has - shares: Decimal, +// Contains some general staking parameters +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] +pub struct StakingInfo { + /// The denominator of the staking token + bonded_denom: String, + /// Time between unbonding and receiving tokens in seconds + unbonding_time: u64, + /// Interest rate per year (60 * 60 * 24 * 365 seconds) + apr: Decimal, } -impl StakeInfo { +/// The number of (conceptual) shares of this validator the staker has. These can be fractional shares +/// Used to calculate the stake. If the validator is slashed, this might not be the same as the stake. +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] +struct Shares(Decimal); + +impl Shares { /// The stake of this delegator. Make sure to pass the correct validator in pub fn stake(&self, validator: &ValidatorInfo) -> Uint128 { - self.shares / validator.total_shares * validator.stake + self.0 / validator.total_shares * validator.stake + } + + pub fn rewards(&self, validator: &ValidatorInfo, rewards: Decimal) -> Decimal { + self.0 * rewards / validator.total_shares } } + +/// Holds some operational data about a validator #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] struct ValidatorInfo { /// The stakers that have staked with this validator stakers: BTreeSet, /// The whole stake of all stakers stake: Uint128, - /// The block height when this validator was last edited. This is needed for rewards calculation - height: u64, + /// The block time when this validator's rewards were last update. This is needed for rewards calculation. + last_rewards_calculation: Timestamp, /// The total number of shares this validator has issued, only used internally for calculating rewards total_shares: Decimal, - /// The number of available rewards. This is updated whenever a - available_rewards: Decimal, + /// The number of available rewards. This is updated in `calculate_rewards`. + /// It is needed to save the current rewards somewhere before adding / removing stake, + /// since the new stake should only apply to future interest, not past interest. + calculated_rewards: Decimal, } impl ValidatorInfo { - pub fn new(block_height: u64) -> Self { + pub fn new(block_time: Timestamp) -> Self { Self { stakers: BTreeSet::new(), stake: Uint128::zero(), - height: block_height, + last_rewards_calculation: block_time, total_shares: Decimal::zero(), - available_rewards: Decimal::zero(), + calculated_rewards: Decimal::zero(), } } /// Returns the amount of shares a delegator gets for staking the given amount of tokens (bonded_denom) at this point in time. @@ -69,13 +84,15 @@ impl ValidatorInfo { } } -const STAKES: Map<(&Addr, &Addr), StakeInfo> = Map::new("stakes"); +const STAKING_INFO: Item = Item::new("staking_info"); +const STAKES: Map<(&Addr, &Addr), Shares> = Map::new("stakes"); const VALIDATOR_MAP: Map<&Addr, Validator> = Map::new("validator_map"); /// Additional vec of validators, in case the `iterator` feature is disabled const VALIDATORS: Item> = Item::new("validators"); /// Contains additional info for each validator const VALIDATOR_INFO: Map<&Addr, ValidatorInfo> = Map::new("validator_info"); -// TODO: replace with `Deque` +/// The queue of unbonding operations. This is needed because unbonding has a waiting time. See [`StakeKeeper`] +/// TODO: replace with `Deque` const UNBONDING_QUEUE: Item> = Item::new("unbonding_queue"); pub const NAMESPACE_STAKING: &[u8] = b"staking"; @@ -83,12 +100,15 @@ pub const NAMESPACE_STAKING: &[u8] = b"staking"; // We need to expand on this, but we will need this to properly test out staking #[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub enum StakingSudo { + /// Slashes the given percentage of the validator's stake. + /// For now, you cannot slash after the fact in tests. Slash { validator: String, percentage: Decimal, }, /// Causes the unbonding queue to be processed. - /// This needs to be triggered manually, since there is no good place to do this right now + /// This needs to be triggered manually, since there is no good place to do this right now. + /// In cosmos-sdk, this is done in `EndBlock`, but we don't have that here. ProcessQueue {}, } @@ -98,9 +118,6 @@ pub trait Distribution: Module Self { StakeKeeper { - // define this better?? it is an account for everything held by the staking keeper + // The address of the staking module. This holds all staked tokens. module_addr: Addr::unchecked("staking_module"), - bonded_denom: "TOKEN".to_string(), - unbonding_time: 60, } } + /// Provides some general parameters to the stake keeper + pub fn setup(&self, storage: &mut dyn Storage, staking_info: StakingInfo) -> AnyResult<()> { + let mut storage = prefixed(storage, NAMESPACE_STAKING); + + STAKING_INFO.save(&mut storage, &staking_info)?; + Ok(()) + } + pub fn init_stake( &self, storage: &mut dyn Storage, @@ -141,6 +164,7 @@ impl StakeKeeper { validator: Validator, ) -> AnyResult<()> { let mut storage = prefixed(storage, NAMESPACE_STAKING); + let val_addr = api.addr_validate(&validator.address)?; if VALIDATOR_MAP.may_load(&storage, &val_addr)?.is_some() { bail!( @@ -153,69 +177,224 @@ impl StakeKeeper { let mut vec = VALIDATORS.may_load(&storage)?.unwrap_or_default(); vec.push(validator); VALIDATORS.save(&mut storage, &vec)?; - VALIDATOR_INFO.save(&mut storage, &val_addr, &ValidatorInfo::new(block.height))?; + VALIDATOR_INFO.save(&mut storage, &val_addr, &ValidatorInfo::new(block.time))?; Ok(()) } - /// Calculates the staking reward for the given stake based on the fixed ratio set using - /// `set_reward_ratio` - fn calculate_rewards(&self, storage: &dyn Storage, stake: Uint128) -> AnyResult { - todo!("calculate rewards"); + fn get_staking_info(staking_storage: &dyn Storage) -> AnyResult { + Ok(STAKING_INFO + .may_load(staking_storage)? + .unwrap_or_else(|| StakingInfo { + bonded_denom: "TOKEN".to_string(), + unbonding_time: 60, + apr: Decimal::percent(10), + })) + } + + /// Returns the rewards of the given delegator at the given validator + pub fn get_rewards( + &self, + storage: &dyn Storage, + block: &BlockInfo, + delegator: &Addr, + validator: &Addr, + ) -> AnyResult> { + let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); + + let validator_obj = match self.get_validator(&staking_storage, validator)? { + Some(validator) => validator, + None => bail!("non-existent validator {}", validator), + }; + // calculate rewards using fixed ratio + let shares = match STAKES.load(&staking_storage, (delegator, validator)) { + Ok(stakes) => stakes, + Err(_) => { + return Ok(None); + } + }; + let validator_info = VALIDATOR_INFO.load(&staking_storage, validator)?; + + Self::get_rewards_internal( + &staking_storage, + block, + &shares, + &validator_obj, + &validator_info, + ) + .map(Some) + } + + fn get_rewards_internal( + staking_storage: &dyn Storage, + block: &BlockInfo, + shares: &Shares, + validator: &Validator, + validator_info: &ValidatorInfo, + ) -> AnyResult { + let staking_info = Self::get_staking_info(staking_storage)?; + + println!( + "old delegator rewards: {} * {} / {}", + validator_info.calculated_rewards, shares.0, validator_info.total_shares + ); + + // calculate missing rewards without updating the validator to reduce rounding errors + let missing_validator_rewards = Self::calculate_rewards( + block.time, + validator_info.last_rewards_calculation, + staking_info.apr, + validator.commission, + validator_info.stake, + ); + let validator_rewards = validator_info.calculated_rewards + missing_validator_rewards; + + // calculate the delegator's share of those + let delegator_rewards = shares.rewards(validator_info, validator_rewards); + + println!( + "new validator / delegator rewards: {} / {}", + validator_rewards, delegator_rewards + ); + + Ok(Coin { + denom: staking_info.bonded_denom, + amount: Uint128::new(1) * delegator_rewards, // multiplying by 1 to convert Decimal to Uint128 + }) + } + + /// Calculates the rewards that are due since the last calculation. + fn calculate_rewards( + current_time: Timestamp, + since: Timestamp, + interest_rate: Decimal, + validator_commission: Decimal, + stake: Uint128, + ) -> Decimal { + // calculate time since last update (in seconds) + let time_diff = current_time.minus_seconds(since.seconds()).seconds(); + + // using decimal here to reduce rounding error when calling this function a lot + let reward = Decimal::from_ratio(stake, 1u128) + * interest_rate + * Decimal::from_ratio(time_diff, 1u128) + / Decimal::from_ratio(60u128 * 60 * 24 * 365, 1u128); + let commission = reward * validator_commission; + + println!( + "calculated new: 10% * {} - 10% comm. = {}", + stake, + reward - commission + ); + + reward - commission + } + + /// Updates the staking reward for the given validator. This mutates the validator info, + /// but does not save it. + /// Always call this to update rewards before changing a validator stake. + fn update_rewards( + block: &BlockInfo, + staking_info: &StakingInfo, + validator_info: &mut ValidatorInfo, + validator: &Validator, + ) -> AnyResult<()> { + if validator_info.last_rewards_calculation >= block.time { + return Ok(()); + } + + let new_rewards = Self::calculate_rewards( + block.time, + validator_info.last_rewards_calculation, + staking_info.apr, + validator.commission, + validator_info.stake, + ); + + // update validator info, but only if there is at least 1 new token + // Less than one token would not change anything, as only full tokens are presented + // outside of the keeper. + if new_rewards >= Decimal::one() { + validator_info.last_rewards_calculation = block.time; + validator_info.calculated_rewards += new_rewards; + } + Ok(()) } /// Returns the single validator with the given address (or `None` if there is no such validator) - fn get_validator(&self, storage: &dyn Storage, address: &Addr) -> AnyResult> { - Ok(VALIDATOR_MAP.may_load(storage, address)?) + fn get_validator( + &self, + staking_storage: &dyn Storage, + address: &Addr, + ) -> AnyResult> { + Ok(VALIDATOR_MAP.may_load(staking_storage, address)?) } /// Returns all available validators - fn get_validators(&self, storage: &dyn Storage) -> AnyResult> { - Ok(VALIDATORS.may_load(storage)?.unwrap_or_default()) + fn get_validators(&self, staking_storage: &dyn Storage) -> AnyResult> { + Ok(VALIDATORS.may_load(staking_storage)?.unwrap_or_default()) } fn get_stake( &self, - storage: &dyn Storage, + staking_storage: &dyn Storage, account: &Addr, validator: &Addr, - ) -> AnyResult { - let val = STAKES.may_load(storage, (account, validator))?; - let validator_info = VALIDATOR_INFO.may_load(storage, validator)?; - Ok(val - .zip(validator_info) - .map(|(s, validator_info)| s.stake(&validator_info)) - .unwrap_or_default()) + ) -> AnyResult { + let shares = STAKES.may_load(staking_storage, (account, validator))?; + let staking_info = Self::get_staking_info(staking_storage)?; + let validator_info = VALIDATOR_INFO.may_load(staking_storage, validator)?; + Ok(Coin { + amount: shares + .zip(validator_info) + .map(|(s, validator_info)| s.stake(&validator_info)) + .unwrap_or_default(), + denom: staking_info.bonded_denom, + }) } fn add_stake( &self, - storage: &mut dyn Storage, + staking_storage: &mut dyn Storage, block: &BlockInfo, to_address: &Addr, validator: &Addr, amount: Coin, ) -> AnyResult<()> { - self.validate_denom(&amount)?; + self.validate_denom(staking_storage, &amount)?; self.validate_nonzero(&amount)?; - self.update_stake(storage, block, to_address, validator, amount.amount, false) + self.update_stake( + staking_storage, + block, + to_address, + validator, + amount.amount, + false, + ) } fn remove_stake( &self, - storage: &mut dyn Storage, + staking_storage: &mut dyn Storage, block: &BlockInfo, from_address: &Addr, validator: &Addr, amount: Coin, ) -> AnyResult<()> { - self.validate_denom(&amount)?; + self.validate_denom(staking_storage, &amount)?; self.validate_nonzero(&amount)?; - self.update_stake(storage, block, from_address, validator, amount.amount, true) + self.update_stake( + staking_storage, + block, + from_address, + validator, + amount.amount, + true, + ) } fn update_stake( &self, - storage: &mut dyn Storage, + staking_storage: &mut dyn Storage, block: &BlockInfo, delegator: &Addr, validator: &Addr, @@ -225,55 +404,57 @@ impl StakeKeeper { let amount = amount.into(); let mut validator_info = VALIDATOR_INFO - .may_load(storage, validator)? - .unwrap_or_else(|| ValidatorInfo::new(block.height)); + .may_load(staking_storage, validator)? + .unwrap_or_else(|| ValidatorInfo::new(block.time)); let mut stake_info = STAKES - .may_load(storage, (delegator, validator))? - .unwrap_or_else(|| StakeInfo { - height: block.height, - shares: Decimal::zero(), - }); - - // TODO: update rewards and validator_info.height + .may_load(staking_storage, (delegator, validator))? + .unwrap_or_else(|| Shares(Decimal::zero())); + + // update rewards for this validator + if !amount.is_zero() { + let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; + let staking_info = Self::get_staking_info(staking_storage)?; + Self::update_rewards(block, &staking_info, &mut validator_info, &validator_obj)?; + } + // now, we can update the stake if sub { - // remove the corresponding amount of shares let shares = validator_info.shares_for(amount); - stake_info.shares -= shares; + stake_info.0 -= shares; validator_info.stake = validator_info.stake.checked_sub(amount)?; validator_info.total_shares -= shares; } else { let new_shares = validator_info.shares_for(amount); - stake_info.shares += new_shares; + stake_info.0 += new_shares; validator_info.stake = validator_info.stake.checked_add(amount)?; validator_info.total_shares += new_shares; } // save updated values - if stake_info.shares.is_zero() { + if stake_info.0.is_zero() { // no more stake, so remove - STAKES.remove(storage, (delegator, validator)); + STAKES.remove(staking_storage, (delegator, validator)); validator_info.stakers.remove(delegator); } else { - STAKES.save(storage, (delegator, validator), &stake_info)?; + STAKES.save(staking_storage, (delegator, validator), &stake_info)?; validator_info.stakers.insert(delegator.clone()); } // save updated validator info - VALIDATOR_INFO.save(storage, validator, &validator_info)?; + VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; Ok(()) } fn slash( &self, - storage: &mut dyn Storage, + staking_storage: &mut dyn Storage, validator: &Addr, percentage: Decimal, ) -> AnyResult<()> { let mut validator_info = VALIDATOR_INFO - .may_load(storage, validator)? + .may_load(staking_storage, validator)? .ok_or_else(|| anyhow!("validator not found"))?; // TODO: handle rewards? Either update them before slashing or set them to zero, depending on the slashing logic @@ -285,39 +466,30 @@ impl StakeKeeper { if validator_info.stake.is_zero() { // need to remove all stakes for delegator in validator_info.stakers.iter() { - STAKES.remove(storage, (delegator, validator)); + STAKES.remove(staking_storage, (delegator, validator)); } validator_info.stakers.clear(); validator_info.total_shares = Decimal::zero(); } - VALIDATOR_INFO.save(storage, validator, &validator_info)?; + VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; Ok(()) } - /// Filters out all 0 value coins and returns an error if the resulting Vec is empty - fn normalize_amount(&self, amount: Vec) -> AnyResult> { - let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); - if res.is_empty() { - bail!("Cannot transfer empty coins amount") - } else { - Ok(res) - } - } - fn validate_nonzero(&self, amount: &Coin) -> AnyResult<()> { ensure!(!amount.amount.is_zero(), anyhow!("cannot delegate 0 coins")); Ok(()) } // Asserts that the given coin has the proper denominator - fn validate_denom(&self, amount: &Coin) -> AnyResult<()> { + fn validate_denom(&self, staking_storage: &dyn Storage, amount: &Coin) -> AnyResult<()> { + let staking_info = Self::get_staking_info(staking_storage)?; ensure_eq!( amount.denom, - self.bonded_denom, + staking_info.bonded_denom, anyhow!( "cannot delegate coins of denominator {}, only of {}", amount.denom, - self.bonded_denom + staking_info.bonded_denom ) ); Ok(()) @@ -379,7 +551,7 @@ impl Module for StakeKeeper { } StakingMsg::Undelegate { validator, amount } => { let validator = api.addr_validate(&validator)?; - self.validate_denom(&amount)?; + self.validate_denom(&staking_storage, &amount)?; self.validate_nonzero(&amount)?; // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 @@ -395,26 +567,15 @@ impl Module for StakeKeeper { amount.clone(), )?; // add tokens to unbonding queue + let staking_info = Self::get_staking_info(&staking_storage)?; let mut queue = UNBONDING_QUEUE .may_load(&staking_storage)? .unwrap_or_default(); queue.push_back(( sender.clone(), - block.time.plus_seconds(self.unbonding_time), + block.time.plus_seconds(staking_info.unbonding_time), amount.amount.u128(), )); - - // // NB: when you need more tokens for staking rewards you can do something like: - // router.sudo( - // api, - // storage, - // block, - // BankSudo::Mint { - // to_address: self.module_addr.to_string(), - // amount: coins(123456000, "ucosm"), - // } - // .into(), - // )?; Ok(AppResponse { events, data: None }) } StakingMsg::Redelegate { @@ -467,7 +628,9 @@ impl Module for StakeKeeper { Ok(AppResponse::default()) } StakingSudo::ProcessQueue {} => { - let mut queue = UNBONDING_QUEUE.may_load(storage)?.unwrap_or_default(); + let mut queue = UNBONDING_QUEUE + .may_load(&staking_storage)? + .unwrap_or_default(); loop { match queue.front() { @@ -476,6 +639,8 @@ impl Module for StakeKeeper { // remove from queue let (delegator, _, amount) = queue.pop_front().unwrap(); + let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); + let staking_info = Self::get_staking_info(&staking_storage)?; router.execute( api, storage, @@ -483,7 +648,7 @@ impl Module for StakeKeeper { self.module_addr.clone(), BankMsg::Send { to_address: delegator.into_string(), - amount: vec![coin(amount, &self.bonded_denom)], + amount: vec![coin(amount, &staking_info.bonded_denom)], } .into(), )?; @@ -501,13 +666,13 @@ impl Module for StakeKeeper { api: &dyn Api, storage: &dyn Storage, _querier: &dyn Querier, - _block: &BlockInfo, + block: &BlockInfo, request: StakingQuery, ) -> AnyResult { let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); match request { StakingQuery::BondedDenom {} => Ok(to_binary(&BondedDenomResponse { - denom: self.bonded_denom.clone(), + denom: Self::get_staking_info(&staking_storage)?.bonded_denom, })?), StakingQuery::AllDelegations { delegator } => { let delegator = api.addr_validate(&delegator)?; @@ -526,7 +691,7 @@ impl Module for StakeKeeper { Ok(Delegation { delegator, validator: validator.address, - amount: coin(amount.u128(), &self.bonded_denom), + amount, }) }) .collect(); @@ -538,25 +703,34 @@ impl Module for StakeKeeper { validator, } => { let validator_addr = Addr::unchecked(&validator); - let validator_obj = self.get_validator(storage, &validator_addr)?; - if validator_obj.is_none() { - bail!("non-existent validator {}", validator); - } + let validator_obj = match self.get_validator(&staking_storage, &validator_addr)? { + Some(validator) => validator, + None => bail!("non-existent validator {}", validator), + }; let delegator = api.addr_validate(&delegator)?; - let stakes = match self.get_stake(&staking_storage, &delegator, &validator_addr) { + // calculate rewards using fixed ratio + let shares = match STAKES.load(&staking_storage, (&delegator, &validator_addr)) { Ok(stakes) => stakes, Err(_) => { let response = DelegationResponse { delegation: None }; return Ok(to_binary(&response)?); } }; - // calculate rewards using fixed ratio - let reward = self.calculate_rewards(&staking_storage, stakes)?; + let validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; + let stakes = shares.stake(&validator_info); + let reward = Self::get_rewards_internal( + &staking_storage, + block, + &shares, + &validator_obj, + &validator_info, + )?; + let staking_info = Self::get_staking_info(&staking_storage)?; let full_delegation_response = DelegationResponse { delegation: Some(FullDelegation { delegator, validator, - amount: coin(stakes.u128(), &self.bonded_denom), + amount: coin(stakes.u128(), staking_info.bonded_denom), can_redelegate: coin(0, "testcoin"), accumulated_rewards: vec![reward], }), @@ -601,26 +775,54 @@ impl Module for DistributionKeeper { sender: Addr, msg: DistributionMsg, ) -> AnyResult { - // let staking_storage = prefixed(storage, NAMESPACE_STAKING); + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { - // For now it ignores validator as I want to support only one DistributionMsg::WithdrawDelegatorReward { validator } => { - let response: DelegationResponse = from_slice(&router.query( + let validator_addr = api.addr_validate(&validator)?; + + let staking_info = STAKING_INFO.load(&staking_storage)?; + let mut validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; + let validator_obj = VALIDATOR_MAP.load(&staking_storage, &validator_addr)?; + + // update the validator's rewards + StakeKeeper::update_rewards( + block, + &staking_info, + &mut validator_info, + &validator_obj, + )?; + + // remove delegator's share of the rewards + let shares = STAKES.load(&staking_storage, (&sender, &validator_addr))?; + let rewards = shares.rewards(&validator_info, validator_info.calculated_rewards); + validator_info.calculated_rewards -= rewards; + let rewards = Uint128::new(1) * rewards; // convert to Uint128 + + // save updated validator_info + VALIDATOR_INFO.save(&mut staking_storage, &validator_addr, &validator_info)?; + + // directly mint rewards to delegator + router.sudo( api, storage, block, - cosmwasm_std::QueryRequest::Staking(StakingQuery::Delegation { - delegator: sender.to_string(), - validator: validator.clone(), - }), - )?)?; - let reward = &response.delegation.unwrap().accumulated_rewards[0]; + BankSudo::Mint { + to_address: sender.to_string(), + amount: vec![Coin { + amount: rewards, + denom: staking_info.bonded_denom.clone(), + }], + } + .into(), + )?; let events = vec![Event::new("withdraw_delegator_reward") .add_attribute("validator", &validator) .add_attribute("sender", &sender) - .add_attribute("amount", format!("{}{}", reward.amount, reward.denom))]; - // TODO: add balance to sender by sending BankMsg transfer + .add_attribute( + "amount", + format!("{}{}", rewards, staking_info.bonded_denom), + )]; Ok(AppResponse { events, data: None }) } m => bail!("Unsupported distribution message: {:?}", m), @@ -652,12 +854,31 @@ impl Module for DistributionKeeper { #[cfg(test)] mod test { - use crate::app::MockRouter; + use crate::{app::MockRouter, BankKeeper, FailingModule, Router, WasmKeeper}; use super::*; use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; + /// Type alias for default build `Router` to make its reference in typical scenario + type BasicRouter = Router< + BankKeeper, + FailingModule, + WasmKeeper, + StakeKeeper, + DistributionKeeper, + >; + + fn mock_router() -> BasicRouter { + Router { + wasm: WasmKeeper::new(), + bank: BankKeeper::new(), + custom: FailingModule::new(), + staking: StakeKeeper::new(), + distribution: DistributionKeeper::new(), + } + } + #[test] fn add_get_validators() { let api = MockApi::default(); @@ -763,7 +984,7 @@ mod test { let stake_left = stake .get_stake(&staking_storage, &delegator, &validator) .unwrap(); - assert_eq!(stake_left.u128(), 50, "should have slashed 50%"); + assert_eq!(stake_left.amount.u128(), 50, "should have slashed 50%"); // slash all stake @@ -784,6 +1005,188 @@ mod test { let stake_left = stake .get_stake(&staking_storage, &delegator, &validator) .unwrap(); - assert_eq!(stake_left.u128(), 0, "should have slashed whole stake"); + assert_eq!( + stake_left.amount.u128(), + 0, + "should have slashed whole stake" + ); + } + + fn setup_test( + apr: Decimal, + validator_commission: Decimal, + ) -> (MockApi, MockStorage, BasicRouter, BlockInfo, Addr) { + let api = MockApi::default(); + let router = mock_router(); + let mut store = MockStorage::new(); + let block = mock_env().block; + + let validator = api.addr_validate("testvaloper1").unwrap(); + + // setup 10% APR + router + .staking + .setup( + &mut store, + StakingInfo { + bonded_denom: "TOKEN".to_string(), + unbonding_time: 60, + apr, + }, + ) + .unwrap(); + + // add validator + let valoper1 = Validator { + address: "testvaloper1".to_string(), + commission: validator_commission, + max_commission: Decimal::percent(100), + max_change_rate: Decimal::percent(1), + }; + router + .staking + .add_validator(&api, &mut store, &block, valoper1) + .unwrap(); + + (api, store, router, block, validator) + } + + #[test] + fn rewards_work_for_single_delegator() { + let (api, mut store, router, mut block, validator) = + setup_test(Decimal::percent(10), Decimal::percent(10)); + let stake = &router.staking; + let distr = &router.distribution; + let delegator = Addr::unchecked("delegator"); + + let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + // stake 200 tokens + stake + .add_stake( + &mut staking_storage, + &block, + &delegator, + &validator, + coin(200, "TOKEN"), + ) + .unwrap(); + + // wait 1/2 year + block.time = block.time.plus_seconds(60 * 60 * 24 * 365 / 2); + + // should now have 200 * 10% / 2 - 10% commission = 9 tokens reward + let rewards = stake + .get_rewards(&store, &block, &delegator, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 9, "should have 9 tokens reward"); + + // withdraw rewards + distr + .execute( + &api, + &mut store, + &router, + &block, + delegator.clone(), + DistributionMsg::WithdrawDelegatorReward { + validator: validator.to_string(), + }, + ) + .unwrap(); + + // should have no rewards left + let rewards = stake + .get_rewards(&store, &block, &delegator, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 0); + + // wait another 1/2 year + block.time = block.time.plus_seconds(60 * 60 * 24 * 365 / 2); + // should now have 9 tokens again + let rewards = stake + .get_rewards(&store, &block, &delegator, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 9); + } + + #[test] + fn rewards_work_for_multiple_delegators() { + let (api, mut store, router, mut block, validator) = + setup_test(Decimal::percent(10), Decimal::percent(10)); + let stake = &router.staking; + let distr = &router.distribution; + let delegator1 = Addr::unchecked("delegator1"); + let delegator2 = Addr::unchecked("delegator2"); + + let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + + // add 100 stake to delegator1 and 200 to delegator2 + stake + .add_stake( + &mut staking_storage, + &block, + &delegator1, + &validator, + coin(100, "TOKEN"), + ) + .unwrap(); + stake + .add_stake( + &mut staking_storage, + &block, + &delegator2, + &validator, + coin(200, "TOKEN"), + ) + .unwrap(); + + // wait 1 year + block.time = block.time.plus_seconds(60 * 60 * 24 * 365); + + // delegator1 should now have 100 * 10% - 10% commission = 9 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator1, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 9); + + // delegator1 should now have 200 * 10% - 10% commission = 18 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator2, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 18); + + // delegator1 stakes 100 more + let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + stake + .add_stake( + &mut staking_storage, + &block, + &delegator1, + &validator, + coin(100, "TOKEN"), + ) + .unwrap(); + + // wait another year + block.time = block.time.plus_seconds(60 * 60 * 24 * 365); + + // delegator1 should now have 9 + 200 * 10% - 10% commission = 27 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator1, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 27); + + // delegator1 should now have 18 + 200 * 10% - 10% commission = 36 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator2, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 36); } } From 735b38cafd2fa8ea57aefd78e57570455802cc02 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 6 Oct 2022 16:41:04 +0200 Subject: [PATCH 523/631] Fix multi-test staking rewards --- packages/multi-test/src/staking.rs | 286 +++++++++++++++++++---------- 1 file changed, 192 insertions(+), 94 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 4cc97628c..d304cf20a 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -28,37 +28,30 @@ pub struct StakingInfo { apr: Decimal, } -/// The number of (conceptual) shares of this validator the staker has. These can be fractional shares -/// Used to calculate the stake. If the validator is slashed, this might not be the same as the stake. +/// The number of stake and rewards of this validator the staker has. These can be fractional in case of slashing. #[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] -struct Shares(Decimal); +struct Shares { + stake: Decimal, + rewards: Decimal, +} impl Shares { - /// The stake of this delegator. Make sure to pass the correct validator in - pub fn stake(&self, validator: &ValidatorInfo) -> Uint128 { - self.0 / validator.total_shares * validator.stake - } - - pub fn rewards(&self, validator: &ValidatorInfo, rewards: Decimal) -> Decimal { - self.0 * rewards / validator.total_shares + /// Calculates the share of validator rewards that should be given to this staker. + pub fn share_of_rewards(&self, validator: &ValidatorInfo, rewards: Decimal) -> Decimal { + rewards * self.stake / validator.stake } } /// Holds some operational data about a validator #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] struct ValidatorInfo { - /// The stakers that have staked with this validator + /// The stakers that have staked with this validator. + /// We need to track them for updating their rewards. stakers: BTreeSet, /// The whole stake of all stakers stake: Uint128, /// The block time when this validator's rewards were last update. This is needed for rewards calculation. last_rewards_calculation: Timestamp, - /// The total number of shares this validator has issued, only used internally for calculating rewards - total_shares: Decimal, - /// The number of available rewards. This is updated in `calculate_rewards`. - /// It is needed to save the current rewards somewhere before adding / removing stake, - /// since the new stake should only apply to future interest, not past interest. - calculated_rewards: Decimal, } impl ValidatorInfo { @@ -67,19 +60,6 @@ impl ValidatorInfo { stakers: BTreeSet::new(), stake: Uint128::zero(), last_rewards_calculation: block_time, - total_shares: Decimal::zero(), - calculated_rewards: Decimal::zero(), - } - } - /// Returns the amount of shares a delegator gets for staking the given amount of tokens (bonded_denom) at this point in time. - /// This should usually be `1:1` unless the delegator was slashed. - pub fn shares_for(&self, stake: Uint128) -> Decimal { - if self.stake.is_zero() { - // first staker always gets 1:1 - Decimal::one() - } else { - Decimal::from_ratio(stake, 1u128) * self.total_shares - / Decimal::from_ratio(self.stake, 1u128) } } } @@ -101,7 +81,7 @@ pub const NAMESPACE_STAKING: &[u8] = b"staking"; #[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] pub enum StakingSudo { /// Slashes the given percentage of the validator's stake. - /// For now, you cannot slash after the fact in tests. + /// For now, you cannot slash retrospectively in tests. Slash { validator: String, percentage: Decimal, @@ -144,6 +124,7 @@ impl StakeKeeper { pub fn init_stake( &self, + api: &dyn Api, storage: &mut dyn Storage, block: &BlockInfo, account: &Addr, @@ -152,7 +133,7 @@ impl StakeKeeper { ) -> AnyResult<()> { let mut storage = prefixed(storage, NAMESPACE_STAKING); - self.add_stake(&mut storage, block, account, validator, amount) + self.add_stake(api, &mut storage, block, account, validator, amount) } /// Add a new validator available for staking @@ -233,28 +214,18 @@ impl StakeKeeper { ) -> AnyResult { let staking_info = Self::get_staking_info(staking_storage)?; - println!( - "old delegator rewards: {} * {} / {}", - validator_info.calculated_rewards, shares.0, validator_info.total_shares - ); - // calculate missing rewards without updating the validator to reduce rounding errors - let missing_validator_rewards = Self::calculate_rewards( + let new_validator_rewards = Self::calculate_rewards( block.time, validator_info.last_rewards_calculation, staking_info.apr, validator.commission, validator_info.stake, ); - let validator_rewards = validator_info.calculated_rewards + missing_validator_rewards; // calculate the delegator's share of those - let delegator_rewards = shares.rewards(validator_info, validator_rewards); - - println!( - "new validator / delegator rewards: {} / {}", - validator_rewards, delegator_rewards - ); + let delegator_rewards = + shares.rewards + shares.share_of_rewards(validator_info, new_validator_rewards); Ok(Coin { denom: staking_info.bonded_denom, @@ -280,12 +251,6 @@ impl StakeKeeper { / Decimal::from_ratio(60u128 * 60 * 24 * 365, 1u128); let commission = reward * validator_commission; - println!( - "calculated new: 10% * {} - 10% comm. = {}", - stake, - reward - commission - ); - reward - commission } @@ -293,6 +258,8 @@ impl StakeKeeper { /// but does not save it. /// Always call this to update rewards before changing a validator stake. fn update_rewards( + api: &dyn Api, + staking_storage: &mut dyn Storage, block: &BlockInfo, staking_info: &StakingInfo, validator_info: &mut ValidatorInfo, @@ -310,12 +277,24 @@ impl StakeKeeper { validator_info.stake, ); - // update validator info, but only if there is at least 1 new token - // Less than one token would not change anything, as only full tokens are presented - // outside of the keeper. - if new_rewards >= Decimal::one() { + // update validator info and delegators + if !new_rewards.is_zero() { validator_info.last_rewards_calculation = block.time; - validator_info.calculated_rewards += new_rewards; + + let validator_addr = api.addr_validate(&validator.address)?; + // update all delegators + for staker in validator_info.stakers.iter() { + STAKES.update( + staking_storage, + (staker, &validator_addr), + |shares| -> AnyResult<_> { + let mut shares = + shares.expect("all stakers in validator_info should exist"); + shares.rewards += shares.share_of_rewards(validator_info, new_rewards); + Ok(shares) + }, + )?; + } } Ok(()) } @@ -342,11 +321,9 @@ impl StakeKeeper { ) -> AnyResult { let shares = STAKES.may_load(staking_storage, (account, validator))?; let staking_info = Self::get_staking_info(staking_storage)?; - let validator_info = VALIDATOR_INFO.may_load(staking_storage, validator)?; Ok(Coin { amount: shares - .zip(validator_info) - .map(|(s, validator_info)| s.stake(&validator_info)) + .map(|s| s.stake * Uint128::new(1)) .unwrap_or_default(), denom: staking_info.bonded_denom, }) @@ -354,6 +331,7 @@ impl StakeKeeper { fn add_stake( &self, + api: &dyn Api, staking_storage: &mut dyn Storage, block: &BlockInfo, to_address: &Addr, @@ -363,6 +341,7 @@ impl StakeKeeper { self.validate_denom(staking_storage, &amount)?; self.validate_nonzero(&amount)?; self.update_stake( + api, staking_storage, block, to_address, @@ -374,6 +353,7 @@ impl StakeKeeper { fn remove_stake( &self, + api: &dyn Api, staking_storage: &mut dyn Storage, block: &BlockInfo, from_address: &Addr, @@ -383,6 +363,7 @@ impl StakeKeeper { self.validate_denom(staking_storage, &amount)?; self.validate_nonzero(&amount)?; self.update_stake( + api, staking_storage, block, from_address, @@ -394,6 +375,7 @@ impl StakeKeeper { fn update_stake( &self, + api: &dyn Api, staking_storage: &mut dyn Storage, block: &BlockInfo, delegator: &Addr, @@ -403,42 +385,46 @@ impl StakeKeeper { ) -> AnyResult<()> { let amount = amount.into(); + if amount.is_zero() { + return Ok(()); + } + let mut validator_info = VALIDATOR_INFO .may_load(staking_storage, validator)? .unwrap_or_else(|| ValidatorInfo::new(block.time)); - let mut stake_info = STAKES - .may_load(staking_storage, (delegator, validator))? - .unwrap_or_else(|| Shares(Decimal::zero())); // update rewards for this validator - if !amount.is_zero() { - let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; - let staking_info = Self::get_staking_info(staking_storage)?; - Self::update_rewards(block, &staking_info, &mut validator_info, &validator_obj)?; - } + let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; + let staking_info = Self::get_staking_info(staking_storage)?; + Self::update_rewards( + api, + staking_storage, + block, + &staking_info, + &mut validator_info, + &validator_obj, + )?; - // now, we can update the stake + // now, we can update the stake of the delegator and validator + let mut shares = STAKES + .may_load(staking_storage, (delegator, validator))? + .unwrap_or_default(); + let amount_dec = Decimal::from_ratio(amount, 1u128); if sub { - let shares = validator_info.shares_for(amount); - stake_info.0 -= shares; - + shares.stake -= amount_dec; validator_info.stake = validator_info.stake.checked_sub(amount)?; - validator_info.total_shares -= shares; } else { - let new_shares = validator_info.shares_for(amount); - stake_info.0 += new_shares; - + shares.stake += amount_dec; validator_info.stake = validator_info.stake.checked_add(amount)?; - validator_info.total_shares += new_shares; } // save updated values - if stake_info.0.is_zero() { + if shares.stake.is_zero() { // no more stake, so remove STAKES.remove(staking_storage, (delegator, validator)); validator_info.stakers.remove(delegator); } else { - STAKES.save(staking_storage, (delegator, validator), &stake_info)?; + STAKES.save(staking_storage, (delegator, validator), &shares)?; validator_info.stakers.insert(delegator.clone()); } // save updated validator info @@ -469,7 +455,20 @@ impl StakeKeeper { STAKES.remove(staking_storage, (delegator, validator)); } validator_info.stakers.clear(); - validator_info.total_shares = Decimal::zero(); + } else { + // otherwise we update all stakers + for delegator in validator_info.stakers.iter() { + STAKES.update( + staking_storage, + (delegator, validator), + |stake| -> AnyResult<_> { + let mut stake = stake.expect("all stakers in validator_info should exist"); + stake.stake *= remaining_percentage; + + Ok(stake) + }, + )?; + } } VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; Ok(()) @@ -529,6 +528,7 @@ impl Module for StakeKeeper { .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) .add_attribute("new_shares", amount.amount.to_string())]; // TODO: calculate shares? self.add_stake( + api, &mut staking_storage, block, &sender, @@ -560,6 +560,7 @@ impl Module for StakeKeeper { .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) .add_attribute("completion_time", "2022-09-27T14:00:00+00:00")]; // TODO: actual date? self.remove_stake( + api, &mut staking_storage, block, &sender, @@ -592,13 +593,21 @@ impl Module for StakeKeeper { .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; self.remove_stake( + api, &mut staking_storage, block, &sender, &src_validator, amount.clone(), )?; - self.add_stake(&mut staking_storage, block, &sender, &dst_validator, amount)?; + self.add_stake( + api, + &mut staking_storage, + block, + &sender, + &dst_validator, + amount, + )?; Ok(AppResponse { events, data: None }) } @@ -717,7 +726,6 @@ impl Module for StakeKeeper { } }; let validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; - let stakes = shares.stake(&validator_info); let reward = Self::get_rewards_internal( &staking_storage, block, @@ -730,8 +738,11 @@ impl Module for StakeKeeper { delegation: Some(FullDelegation { delegator, validator, - amount: coin(stakes.u128(), staking_info.bonded_denom), - can_redelegate: coin(0, "testcoin"), + amount: coin( + (shares.stake * Uint128::new(1)).u128(), + staking_info.bonded_denom, + ), + can_redelegate: coin(0, "testcoin"), // TODO: not implemented right now accumulated_rewards: vec![reward], }), }; @@ -784,23 +795,26 @@ impl Module for DistributionKeeper { let mut validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; let validator_obj = VALIDATOR_MAP.load(&staking_storage, &validator_addr)?; - // update the validator's rewards + // update the validator and staker rewards StakeKeeper::update_rewards( + api, + &mut staking_storage, block, &staking_info, &mut validator_info, &validator_obj, )?; - - // remove delegator's share of the rewards - let shares = STAKES.load(&staking_storage, (&sender, &validator_addr))?; - let rewards = shares.rewards(&validator_info, validator_info.calculated_rewards); - validator_info.calculated_rewards -= rewards; - let rewards = Uint128::new(1) * rewards; // convert to Uint128 - // save updated validator_info VALIDATOR_INFO.save(&mut staking_storage, &validator_addr, &validator_info)?; + // load updated rewards for delegator + let mut shares = STAKES.load(&staking_storage, (&sender, &validator_addr))?; + let rewards = Uint128::new(1) * shares.rewards; // convert to Uint128 + + // remove rewards from delegator + shares.rewards = Decimal::zero(); + STAKES.save(&mut staking_storage, (&sender, &validator_addr), &shares)?; + // directly mint rewards to delegator router.sudo( api, @@ -858,7 +872,11 @@ mod test { use super::*; - use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; + use cosmwasm_std::{ + from_slice, + testing::{mock_env, MockApi, MockStorage}, + BalanceResponse, BankQuery, + }; /// Type alias for default build `Router` to make its reference in typical scenario type BasicRouter = Router< @@ -957,6 +975,7 @@ mod test { let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); stake .add_stake( + &api, &mut staking_storage, &block, &delegator, @@ -1063,6 +1082,7 @@ mod test { // stake 200 tokens stake .add_stake( + &api, &mut staking_storage, &block, &delegator, @@ -1118,6 +1138,7 @@ mod test { setup_test(Decimal::percent(10), Decimal::percent(10)); let stake = &router.staking; let distr = &router.distribution; + let bank = &router.bank; let delegator1 = Addr::unchecked("delegator1"); let delegator2 = Addr::unchecked("delegator2"); @@ -1126,6 +1147,7 @@ mod test { // add 100 stake to delegator1 and 200 to delegator2 stake .add_stake( + &api, &mut staking_storage, &block, &delegator1, @@ -1135,6 +1157,7 @@ mod test { .unwrap(); stake .add_stake( + &api, &mut staking_storage, &block, &delegator2, @@ -1153,7 +1176,7 @@ mod test { .unwrap(); assert_eq!(rewards.amount.u128(), 9); - // delegator1 should now have 200 * 10% - 10% commission = 18 tokens + // delegator2 should now have 200 * 10% - 10% commission = 18 tokens let rewards = stake .get_rewards(&store, &block, &delegator2, &validator) .unwrap() @@ -1164,6 +1187,7 @@ mod test { let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); stake .add_stake( + &api, &mut staking_storage, &block, &delegator1, @@ -1182,11 +1206,85 @@ mod test { .unwrap(); assert_eq!(rewards.amount.u128(), 27); - // delegator1 should now have 18 + 200 * 10% - 10% commission = 36 tokens + // delegator2 should now have 18 + 200 * 10% - 10% commission = 36 tokens let rewards = stake .get_rewards(&store, &block, &delegator2, &validator) .unwrap() .unwrap(); assert_eq!(rewards.amount.u128(), 36); + + // delegator2 unstakes 100 (has 100 left after that) + let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); + stake + .remove_stake( + &api, + &mut staking_storage, + &block, + &delegator2, + &validator, + coin(100, "TOKEN"), + ) + .unwrap(); + + // and delegator1 withdraws rewards + distr + .execute( + &api, + &mut store, + &router, + &block, + delegator1.clone(), + DistributionMsg::WithdrawDelegatorReward { + validator: validator.to_string(), + }, + ) + .unwrap(); + + let balance: BalanceResponse = from_slice( + &bank + .query( + &api, + &store, + &router.querier(&api, &store, &block), + &block, + BankQuery::Balance { + address: delegator1.to_string(), + denom: "TOKEN".to_string(), + }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + balance.amount.amount.u128(), + 27, + "withdraw should change bank balance" + ); + let rewards = stake + .get_rewards(&store, &block, &delegator1, &validator) + .unwrap() + .unwrap(); + assert_eq!( + rewards.amount.u128(), + 0, + "withdraw should reduce rewards to 0" + ); + + // wait another year + block.time = block.time.plus_seconds(60 * 60 * 24 * 365); + + // delegator1 should now have 0 + 200 * 10% - 10% commission = 18 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator1, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 18); + + // delegator2 should now have 36 + 100 * 10% - 10% commission = 45 tokens + let rewards = stake + .get_rewards(&store, &block, &delegator2, &validator) + .unwrap() + .unwrap(); + assert_eq!(rewards.amount.u128(), 45); } } From cf3c94b97670c3d4162b1e0fce19fb7210697ebb Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 6 Oct 2022 17:00:40 +0200 Subject: [PATCH 524/631] Cleanup --- packages/multi-test/src/staking.rs | 85 ++++++++++++++---------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index d304cf20a..1b468756b 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -254,17 +254,23 @@ impl StakeKeeper { reward - commission } - /// Updates the staking reward for the given validator. This mutates the validator info, - /// but does not save it. - /// Always call this to update rewards before changing a validator stake. + /// Updates the staking reward for the given validator and their stakers + /// It saves the validator info and it's stakers, so make sure not to overwrite that. + /// Always call this to update rewards before changing anything that influences future rewards. fn update_rewards( api: &dyn Api, staking_storage: &mut dyn Storage, block: &BlockInfo, - staking_info: &StakingInfo, - validator_info: &mut ValidatorInfo, - validator: &Validator, + validator: &Addr, ) -> AnyResult<()> { + let staking_info = Self::get_staking_info(staking_storage)?; + + let mut validator_info = VALIDATOR_INFO + .may_load(staking_storage, validator)? + .ok_or_else(|| anyhow!("validator not found"))?; + + let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; + if validator_info.last_rewards_calculation >= block.time { return Ok(()); } @@ -273,7 +279,7 @@ impl StakeKeeper { block.time, validator_info.last_rewards_calculation, staking_info.apr, - validator.commission, + validator_obj.commission, validator_info.stake, ); @@ -281,7 +287,10 @@ impl StakeKeeper { if !new_rewards.is_zero() { validator_info.last_rewards_calculation = block.time; - let validator_addr = api.addr_validate(&validator.address)?; + // save updated validator + VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; + + let validator_addr = api.addr_validate(&validator_obj.address)?; // update all delegators for staker in validator_info.stakers.iter() { STAKES.update( @@ -290,7 +299,7 @@ impl StakeKeeper { |shares| -> AnyResult<_> { let mut shares = shares.expect("all stakers in validator_info should exist"); - shares.rewards += shares.share_of_rewards(validator_info, new_rewards); + shares.rewards += shares.share_of_rewards(&validator_info, new_rewards); Ok(shares) }, )?; @@ -389,23 +398,15 @@ impl StakeKeeper { return Ok(()); } - let mut validator_info = VALIDATOR_INFO - .may_load(staking_storage, validator)? - .unwrap_or_else(|| ValidatorInfo::new(block.time)); - // update rewards for this validator - let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; - let staking_info = Self::get_staking_info(staking_storage)?; - Self::update_rewards( - api, - staking_storage, - block, - &staking_info, - &mut validator_info, - &validator_obj, - )?; + // let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; + // let staking_info = Self::get_staking_info(staking_storage)?; + Self::update_rewards(api, staking_storage, block, validator)?; // now, we can update the stake of the delegator and validator + let mut validator_info = VALIDATOR_INFO + .may_load(staking_storage, validator)? + .unwrap_or_else(|| ValidatorInfo::new(block.time)); let mut shares = STAKES .may_load(staking_storage, (delegator, validator))? .unwrap_or_default(); @@ -435,16 +436,20 @@ impl StakeKeeper { fn slash( &self, + api: &dyn Api, staking_storage: &mut dyn Storage, + block: &BlockInfo, validator: &Addr, percentage: Decimal, ) -> AnyResult<()> { + // calculate rewards before slashing + Self::update_rewards(api, staking_storage, block, validator)?; + + // update stake of validator and stakers let mut validator_info = VALIDATOR_INFO .may_load(staking_storage, validator)? .ok_or_else(|| anyhow!("validator not found"))?; - // TODO: handle rewards? Either update them before slashing or set them to zero, depending on the slashing logic - let remaining_percentage = Decimal::one() - percentage; validator_info.stake = validator_info.stake * remaining_percentage; @@ -632,7 +637,7 @@ impl Module for StakeKeeper { let validator = api.addr_validate(&validator)?; self.validate_percentage(percentage)?; - self.slash(&mut staking_storage, &validator, percentage)?; + self.slash(api, &mut staking_storage, block, &validator, percentage)?; Ok(AppResponse::default()) } @@ -734,15 +739,16 @@ impl Module for StakeKeeper { &validator_info, )?; let staking_info = Self::get_staking_info(&staking_storage)?; + let amount = coin( + (shares.stake * Uint128::new(1)).u128(), + staking_info.bonded_denom, + ); let full_delegation_response = DelegationResponse { delegation: Some(FullDelegation { delegator, validator, - amount: coin( - (shares.stake * Uint128::new(1)).u128(), - staking_info.bonded_denom, - ), - can_redelegate: coin(0, "testcoin"), // TODO: not implemented right now + amount: amount.clone(), + can_redelegate: amount, // TODO: not implemented right now accumulated_rewards: vec![reward], }), }; @@ -791,21 +797,10 @@ impl Module for DistributionKeeper { DistributionMsg::WithdrawDelegatorReward { validator } => { let validator_addr = api.addr_validate(&validator)?; - let staking_info = STAKING_INFO.load(&staking_storage)?; - let mut validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; - let validator_obj = VALIDATOR_MAP.load(&staking_storage, &validator_addr)?; - // update the validator and staker rewards - StakeKeeper::update_rewards( - api, - &mut staking_storage, - block, - &staking_info, - &mut validator_info, - &validator_obj, - )?; - // save updated validator_info - VALIDATOR_INFO.save(&mut staking_storage, &validator_addr, &validator_info)?; + StakeKeeper::update_rewards(api, &mut staking_storage, block, &validator_addr)?; + + let staking_info = STAKING_INFO.load(&staking_storage)?; // load updated rewards for delegator let mut shares = STAKES.load(&staking_storage, (&sender, &validator_addr))?; From de1ae1f0727c18c62126e295f39873b6ca10af69 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 7 Oct 2022 14:26:52 +0200 Subject: [PATCH 525/631] Add more tests and small fixes --- packages/multi-test/src/staking.rs | 633 +++++++++++++++++++++++++---- 1 file changed, 545 insertions(+), 88 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 1b468756b..a16413851 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -18,7 +18,7 @@ use crate::executor::AppResponse; use crate::{BankSudo, Module}; // Contains some general staking parameters -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct StakingInfo { /// The denominator of the staking token bonded_denom: String, @@ -28,6 +28,16 @@ pub struct StakingInfo { apr: Decimal, } +impl Default for StakingInfo { + fn default() -> Self { + StakingInfo { + bonded_denom: "TOKEN".to_string(), + unbonding_time: 60, + apr: Decimal::percent(10), + } + } +} + /// The number of stake and rewards of this validator the staker has. These can be fractional in case of slashing. #[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] struct Shares { @@ -163,13 +173,7 @@ impl StakeKeeper { } fn get_staking_info(staking_storage: &dyn Storage) -> AnyResult { - Ok(STAKING_INFO - .may_load(staking_storage)? - .unwrap_or_else(|| StakingInfo { - bonded_denom: "TOKEN".to_string(), - unbonding_time: 60, - apr: Decimal::percent(10), - })) + Ok(STAKING_INFO.may_load(staking_storage)?.unwrap_or_default()) } /// Returns the rewards of the given delegator at the given validator @@ -327,15 +331,16 @@ impl StakeKeeper { staking_storage: &dyn Storage, account: &Addr, validator: &Addr, - ) -> AnyResult { + ) -> AnyResult> { let shares = STAKES.may_load(staking_storage, (account, validator))?; let staking_info = Self::get_staking_info(staking_storage)?; - Ok(Coin { - amount: shares - .map(|s| s.stake * Uint128::new(1)) - .unwrap_or_default(), - denom: staking_info.bonded_denom, - }) + + Ok(shares.map(|shares| { + Coin { + denom: staking_info.bonded_denom, + amount: Uint128::new(1) * shares.stake, // multiplying by 1 to convert Decimal to Uint128 + } + })) } fn add_stake( @@ -399,8 +404,6 @@ impl StakeKeeper { } // update rewards for this validator - // let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; - // let staking_info = Self::get_staking_info(staking_storage)?; Self::update_rewards(api, staking_storage, block, validator)?; // now, we can update the stake of the delegator and validator @@ -412,6 +415,9 @@ impl StakeKeeper { .unwrap_or_default(); let amount_dec = Decimal::from_ratio(amount, 1u128); if sub { + if amount_dec > shares.stake { + bail!("insufficient stake"); + } shares.stake -= amount_dec; validator_info.stake = validator_info.stake.checked_sub(amount)?; } else { @@ -582,6 +588,7 @@ impl Module for StakeKeeper { block.time.plus_seconds(staking_info.unbonding_time), amount.amount.u128(), )); + UNBONDING_QUEUE.save(&mut staking_storage, &queue)?; Ok(AppResponse { events, data: None }) } StakingMsg::Redelegate { @@ -694,19 +701,21 @@ impl Module for StakeKeeper { let res: AnyResult> = validators .into_iter() - .map(|validator| { + .filter_map(|validator| { let delegator = delegator.clone(); - let amount = self.get_stake( - &staking_storage, - &delegator, - &Addr::unchecked(&validator.address), - )?; - - Ok(Delegation { + let amount = self + .get_stake( + &staking_storage, + &delegator, + &Addr::unchecked(&validator.address), + ) + .transpose()?; + + Some(amount.map(|amount| Delegation { delegator, validator: validator.address, amount, - }) + })) }) .collect(); @@ -722,7 +731,7 @@ impl Module for StakeKeeper { None => bail!("non-existent validator {}", validator), }; let delegator = api.addr_validate(&delegator)?; - // calculate rewards using fixed ratio + let shares = match STAKES.load(&staking_storage, (&delegator, &validator_addr)) { Ok(stakes) => stakes, Err(_) => { @@ -749,7 +758,11 @@ impl Module for StakeKeeper { validator, amount: amount.clone(), can_redelegate: amount, // TODO: not implemented right now - accumulated_rewards: vec![reward], + accumulated_rewards: if reward.amount.is_zero() { + vec![] + } else { + vec![reward] + }, }), }; @@ -774,6 +787,30 @@ impl DistributionKeeper { pub fn new() -> Self { DistributionKeeper {} } + + /// Removes all rewards from the given (delegator, validator) pair and returns the amount + pub fn remove_rewards( + &self, + api: &dyn Api, + storage: &mut dyn Storage, + block: &BlockInfo, + delegator: &Addr, + validator: &Addr, + ) -> AnyResult { + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + // update the validator and staker rewards + StakeKeeper::update_rewards(api, &mut staking_storage, block, validator)?; + + // load updated rewards for delegator + let mut shares = STAKES.load(&staking_storage, (delegator, validator))?; + let rewards = Uint128::new(1) * shares.rewards; // convert to Uint128 + + // remove rewards from delegator + shares.rewards = Decimal::zero(); + STAKES.save(&mut staking_storage, (delegator, validator), &shares)?; + + Ok(rewards) + } } impl Distribution for DistributionKeeper {} @@ -792,24 +829,14 @@ impl Module for DistributionKeeper { sender: Addr, msg: DistributionMsg, ) -> AnyResult { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { DistributionMsg::WithdrawDelegatorReward { validator } => { let validator_addr = api.addr_validate(&validator)?; - // update the validator and staker rewards - StakeKeeper::update_rewards(api, &mut staking_storage, block, &validator_addr)?; - - let staking_info = STAKING_INFO.load(&staking_storage)?; - - // load updated rewards for delegator - let mut shares = STAKES.load(&staking_storage, (&sender, &validator_addr))?; - let rewards = Uint128::new(1) * shares.rewards; // convert to Uint128 - - // remove rewards from delegator - shares.rewards = Decimal::zero(); - STAKES.save(&mut staking_storage, (&sender, &validator_addr), &shares)?; + let rewards = self.remove_rewards(api, storage, block, &sender, &validator_addr)?; + let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); + let staking_info = StakeKeeper::get_staking_info(&staking_storage)?; // directly mint rewards to delegator router.sudo( api, @@ -892,6 +919,44 @@ mod test { } } + fn setup_test_env( + apr: Decimal, + validator_commission: Decimal, + ) -> (MockApi, MockStorage, BasicRouter, BlockInfo, Addr) { + let api = MockApi::default(); + let router = mock_router(); + let mut store = MockStorage::new(); + let block = mock_env().block; + + let validator = api.addr_validate("testvaloper1").unwrap(); + + router + .staking + .setup( + &mut store, + StakingInfo { + bonded_denom: "TOKEN".to_string(), + unbonding_time: 60, + apr, + }, + ) + .unwrap(); + + // add validator + let valoper1 = Validator { + address: "testvaloper1".to_string(), + commission: validator_commission, + max_commission: Decimal::percent(100), + max_change_rate: Decimal::percent(1), + }; + router + .staking + .add_validator(&api, &mut store, &block, valoper1) + .unwrap(); + + (api, store, router, block, validator) + } + #[test] fn add_get_validators() { let api = MockApi::default(); @@ -998,7 +1063,11 @@ mod test { let stake_left = stake .get_stake(&staking_storage, &delegator, &validator) .unwrap(); - assert_eq!(stake_left.amount.u128(), 50, "should have slashed 50%"); + assert_eq!( + stake_left.unwrap().amount.u128(), + 50, + "should have slashed 50%" + ); // slash all stake @@ -1019,56 +1088,13 @@ mod test { let stake_left = stake .get_stake(&staking_storage, &delegator, &validator) .unwrap(); - assert_eq!( - stake_left.amount.u128(), - 0, - "should have slashed whole stake" - ); - } - - fn setup_test( - apr: Decimal, - validator_commission: Decimal, - ) -> (MockApi, MockStorage, BasicRouter, BlockInfo, Addr) { - let api = MockApi::default(); - let router = mock_router(); - let mut store = MockStorage::new(); - let block = mock_env().block; - - let validator = api.addr_validate("testvaloper1").unwrap(); - - // setup 10% APR - router - .staking - .setup( - &mut store, - StakingInfo { - bonded_denom: "TOKEN".to_string(), - unbonding_time: 60, - apr, - }, - ) - .unwrap(); - - // add validator - let valoper1 = Validator { - address: "testvaloper1".to_string(), - commission: validator_commission, - max_commission: Decimal::percent(100), - max_change_rate: Decimal::percent(1), - }; - router - .staking - .add_validator(&api, &mut store, &block, valoper1) - .unwrap(); - - (api, store, router, block, validator) + assert_eq!(stake_left, None, "should have slashed whole stake"); } #[test] fn rewards_work_for_single_delegator() { let (api, mut store, router, mut block, validator) = - setup_test(Decimal::percent(10), Decimal::percent(10)); + setup_test_env(Decimal::percent(10), Decimal::percent(10)); let stake = &router.staking; let distr = &router.distribution; let delegator = Addr::unchecked("delegator"); @@ -1130,7 +1156,7 @@ mod test { #[test] fn rewards_work_for_multiple_delegators() { let (api, mut store, router, mut block, validator) = - setup_test(Decimal::percent(10), Decimal::percent(10)); + setup_test_env(Decimal::percent(10), Decimal::percent(10)); let stake = &router.staking; let distr = &router.distribution; let bank = &router.bank; @@ -1282,4 +1308,435 @@ mod test { .unwrap(); assert_eq!(rewards.amount.u128(), 45); } + + mod msg { + use cosmwasm_std::{from_slice, Addr, BondedDenomResponse, Decimal, StakingQuery}; + use serde::de::DeserializeOwned; + + use super::*; + + // shortens tests a bit + struct TestEnv { + api: MockApi, + store: MockStorage, + router: BasicRouter, + block: BlockInfo, + } + + impl TestEnv { + fn wrap(tuple: (MockApi, MockStorage, BasicRouter, BlockInfo, Addr)) -> (Self, Addr) { + ( + Self { + api: tuple.0, + store: tuple.1, + router: tuple.2, + block: tuple.3, + }, + tuple.4, + ) + } + } + + fn execute_stake( + env: &mut TestEnv, + sender: Addr, + msg: StakingMsg, + ) -> AnyResult { + env.router.staking.execute( + &env.api, + &mut env.store, + &env.router, + &env.block, + sender, + msg, + ) + } + + fn query_stake(env: &TestEnv, msg: StakingQuery) -> AnyResult { + Ok(from_slice(&env.router.staking.query( + &env.api, + &env.store, + &env.router.querier(&env.api, &env.store, &env.block), + &env.block, + msg, + )?)?) + } + + fn execute_distr( + env: &mut TestEnv, + sender: Addr, + msg: DistributionMsg, + ) -> AnyResult { + env.router.distribution.execute( + &env.api, + &mut env.store, + &env.router, + &env.block, + sender, + msg, + ) + } + + fn query_bank(env: &TestEnv, msg: BankQuery) -> AnyResult { + Ok(from_slice(&env.router.bank.query( + &env.api, + &env.store, + &env.router.querier(&env.api, &env.store, &env.block), + &env.block, + msg, + )?)?) + } + + fn assert_balances(env: &TestEnv, balances: impl IntoIterator) { + for (addr, amount) in balances { + let balance: BalanceResponse = query_bank( + env, + BankQuery::Balance { + address: addr.to_string(), + denom: "TOKEN".to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.amount.amount.u128(), amount); + } + } + + #[test] + fn execute() { + // test all execute msgs + let (mut test_env, validator1) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + + let delegator1 = Addr::unchecked("delegator1"); + + // fund delegator1 account + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator1, vec![coin(1000, "TOKEN")]) + .unwrap(); + + // add second validator + let validator2 = Addr::unchecked("validator2"); + test_env + .router + .staking + .add_validator( + &test_env.api, + &mut test_env.store, + &test_env.block, + Validator { + address: validator2.to_string(), + commission: Decimal::zero(), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }, + ) + .unwrap(); + + // delegate 100 tokens to validator1 + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Delegate { + validator: validator1.to_string(), + amount: coin(100, "TOKEN"), + }, + ) + .unwrap(); + + // should now have 100 tokens less + assert_balances(&test_env, vec![(delegator1.clone(), 900)]); + + // wait a year + test_env.block.time = test_env.block.time.plus_seconds(60 * 60 * 24 * 365); + + // withdraw rewards + execute_distr( + &mut test_env, + delegator1.clone(), + DistributionMsg::WithdrawDelegatorReward { + validator: validator1.to_string(), + }, + ) + .unwrap(); + + // redelegate to validator2 + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Redelegate { + src_validator: validator1.to_string(), + dst_validator: validator2.to_string(), + amount: coin(100, "TOKEN"), + }, + ) + .unwrap(); + + // should have same amount as before + assert_balances( + &test_env, + vec![(delegator1.clone(), 900 + 100 / 10 * 9 / 10)], + ); + + let delegations: AllDelegationsResponse = query_stake( + &test_env, + StakingQuery::AllDelegations { + delegator: delegator1.to_string(), + }, + ) + .unwrap(); + assert_eq!( + delegations.delegations, + [Delegation { + delegator: delegator1.clone(), + validator: validator2.to_string(), + amount: coin(100, "TOKEN"), + }] + ); + + // undelegate all tokens + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Undelegate { + validator: validator2.to_string(), + amount: coin(100, "TOKEN"), + }, + ) + .unwrap(); + + // wait for unbonding period (60 seconds in default config) + test_env.block.time = test_env.block.time.plus_seconds(60); + + // need to manually cause queue to get processed + test_env + .router + .staking + .sudo( + &test_env.api, + &mut test_env.store, + &test_env.router, + &test_env.block, + StakingSudo::ProcessQueue {}, + ) + .unwrap(); + + // check bank balance + assert_balances( + &test_env, + vec![(delegator1.clone(), 1000 + 100 / 10 * 9 / 10)], + ); + } + + #[test] + fn cannot_steal() { + let (mut test_env, validator1) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + + let delegator1 = Addr::unchecked("delegator1"); + + // fund delegator1 account + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "TOKEN")]) + .unwrap(); + + // delegate 100 tokens to validator1 + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Delegate { + validator: validator1.to_string(), + amount: coin(100, "TOKEN"), + }, + ) + .unwrap(); + + // undelegate more tokens than we have + let e = execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Undelegate { + validator: validator1.to_string(), + amount: coin(200, "TOKEN"), + }, + ) + .unwrap_err(); + + assert_eq!(e.to_string(), "insufficient stake"); + + // add second validator + let validator2 = Addr::unchecked("validator2"); + test_env + .router + .staking + .add_validator( + &test_env.api, + &mut test_env.store, + &test_env.block, + Validator { + address: validator2.to_string(), + commission: Decimal::zero(), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }, + ) + .unwrap(); + + // redelegate more tokens than we have + let e = execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Redelegate { + src_validator: validator1.to_string(), + dst_validator: validator2.to_string(), + amount: coin(200, "TOKEN"), + }, + ) + .unwrap_err(); + assert_eq!(e.to_string(), "insufficient stake"); + } + + #[test] + fn query_staking() { + // run all staking queries + let (mut test_env, validator1) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + let delegator1 = Addr::unchecked("delegator1"); + let delegator2 = Addr::unchecked("delegator2"); + + // init balances + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator1, vec![coin(260, "TOKEN")]) + .unwrap(); + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator2, vec![coin(150, "TOKEN")]) + .unwrap(); + + // add another validator + let validator2 = test_env.api.addr_validate("testvaloper2").unwrap(); + let valoper2 = Validator { + address: "testvaloper2".to_string(), + commission: Decimal::percent(0), + max_commission: Decimal::percent(1), + max_change_rate: Decimal::percent(1), + }; + test_env + .router + .staking + .add_validator( + &test_env.api, + &mut test_env.store, + &test_env.block, + valoper2.clone(), + ) + .unwrap(); + + // query validators + let valoper1: ValidatorResponse = query_stake( + &test_env, + StakingQuery::Validator { + address: validator1.to_string(), + }, + ) + .unwrap(); + let validators: AllValidatorsResponse = + query_stake(&test_env, StakingQuery::AllValidators {}).unwrap(); + assert_eq!( + validators.validators, + [valoper1.validator.unwrap(), valoper2] + ); + // query non-existent validator + let response = query_stake::( + &test_env, + StakingQuery::Validator { + address: "notvaloper".to_string(), + }, + ) + .unwrap(); + assert_eq!(response.validator, None); + + // query bonded denom + let response: BondedDenomResponse = + query_stake(&test_env, StakingQuery::BondedDenom {}).unwrap(); + assert_eq!(response.denom, "TOKEN"); + + // delegate some tokens with delegator1 and delegator2 + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Delegate { + validator: validator1.to_string(), + amount: coin(100, "TOKEN"), + }, + ) + .unwrap(); + execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Delegate { + validator: validator2.to_string(), + amount: coin(160, "TOKEN"), + }, + ) + .unwrap(); + execute_stake( + &mut test_env, + delegator2.clone(), + StakingMsg::Delegate { + validator: validator1.to_string(), + amount: coin(150, "TOKEN"), + }, + ) + .unwrap(); + + // query all delegations + let response1: AllDelegationsResponse = query_stake( + &test_env, + StakingQuery::AllDelegations { + delegator: delegator1.to_string(), + }, + ) + .unwrap(); + assert_eq!( + response1.delegations, + vec![ + Delegation { + delegator: delegator1.clone(), + validator: validator1.to_string(), + amount: coin(100, "TOKEN"), + }, + Delegation { + delegator: delegator1.clone(), + validator: validator2.to_string(), + amount: coin(160, "TOKEN"), + }, + ] + ); + let response2: DelegationResponse = query_stake( + &test_env, + StakingQuery::Delegation { + delegator: delegator2.to_string(), + validator: validator1.to_string(), + }, + ) + .unwrap(); + assert_eq!( + response2.delegation.unwrap(), + FullDelegation { + delegator: delegator2.clone(), + validator: validator1.to_string(), + amount: coin(150, "TOKEN"), + accumulated_rewards: vec![], + can_redelegate: coin(150, "TOKEN"), + }, + ); + } + } } From b4882f28ae0aa2b14a5dbfc7e06ef0f8067f70ba Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 7 Oct 2022 14:29:27 +0200 Subject: [PATCH 526/631] Add stake and distribution keeper to BasicApp --- packages/multi-test/src/app.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 18e498418..9087cebf1 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -33,6 +33,8 @@ pub type BasicApp = App< MockStorage, FailingModule, WasmKeeper, + StakeKeeper, + DistributionKeeper, >; /// Router is a persisted state. You can query this. From 31aaa5e893c310496e0a1edef657bbd54f23380a Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 7 Oct 2022 14:53:07 +0200 Subject: [PATCH 527/631] Use Deque in staking test module --- packages/multi-test/src/staking.rs | 49 ++++++++++++++---------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index a16413851..d9b8e1026 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeSet, VecDeque}; +use std::collections::BTreeSet; use anyhow::{anyhow, bail, Result as AnyResult}; use schemars::JsonSchema; @@ -10,7 +10,7 @@ use cosmwasm_std::{ StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, }; use cosmwasm_storage::{prefixed, prefixed_read}; -use cw_storage_plus::{Item, Map}; +use cw_storage_plus::{Deque, Item, Map}; use serde::{Deserialize, Serialize}; use crate::app::CosmosRouter; @@ -78,12 +78,11 @@ const STAKING_INFO: Item = Item::new("staking_info"); const STAKES: Map<(&Addr, &Addr), Shares> = Map::new("stakes"); const VALIDATOR_MAP: Map<&Addr, Validator> = Map::new("validator_map"); /// Additional vec of validators, in case the `iterator` feature is disabled -const VALIDATORS: Item> = Item::new("validators"); +const VALIDATORS: Deque = Deque::new("validators"); /// Contains additional info for each validator const VALIDATOR_INFO: Map<&Addr, ValidatorInfo> = Map::new("validator_info"); /// The queue of unbonding operations. This is needed because unbonding has a waiting time. See [`StakeKeeper`] -/// TODO: replace with `Deque` -const UNBONDING_QUEUE: Item> = Item::new("unbonding_queue"); +const UNBONDING_QUEUE: Deque<(Addr, Timestamp, u128)> = Deque::new("unbonding_queue"); pub const NAMESPACE_STAKING: &[u8] = b"staking"; @@ -165,9 +164,7 @@ impl StakeKeeper { } VALIDATOR_MAP.save(&mut storage, &val_addr, &validator)?; - let mut vec = VALIDATORS.may_load(&storage)?.unwrap_or_default(); - vec.push(validator); - VALIDATORS.save(&mut storage, &vec)?; + VALIDATORS.push_back(&mut storage, &validator)?; VALIDATOR_INFO.save(&mut storage, &val_addr, &ValidatorInfo::new(block.time))?; Ok(()) } @@ -323,7 +320,8 @@ impl StakeKeeper { /// Returns all available validators fn get_validators(&self, staking_storage: &dyn Storage) -> AnyResult> { - Ok(VALIDATORS.may_load(staking_storage)?.unwrap_or_default()) + let res: Result<_, _> = VALIDATORS.iter(staking_storage)?.collect(); + Ok(res?) } fn get_stake( @@ -580,15 +578,14 @@ impl Module for StakeKeeper { )?; // add tokens to unbonding queue let staking_info = Self::get_staking_info(&staking_storage)?; - let mut queue = UNBONDING_QUEUE - .may_load(&staking_storage)? - .unwrap_or_default(); - queue.push_back(( - sender.clone(), - block.time.plus_seconds(staking_info.unbonding_time), - amount.amount.u128(), - )); - UNBONDING_QUEUE.save(&mut staking_storage, &queue)?; + UNBONDING_QUEUE.push_back( + &mut staking_storage, + &( + sender.clone(), + block.time.plus_seconds(staking_info.unbonding_time), + amount.amount.u128(), + ), + )?; Ok(AppResponse { events, data: None }) } StakingMsg::Redelegate { @@ -635,12 +632,12 @@ impl Module for StakeKeeper { block: &BlockInfo, msg: StakingSudo, ) -> AnyResult { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); match msg { StakingSudo::Slash { validator, percentage, } => { + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); let validator = api.addr_validate(&validator)?; self.validate_percentage(percentage)?; @@ -649,18 +646,16 @@ impl Module for StakeKeeper { Ok(AppResponse::default()) } StakingSudo::ProcessQueue {} => { - let mut queue = UNBONDING_QUEUE - .may_load(&staking_storage)? - .unwrap_or_default(); - loop { - match queue.front() { + let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); + let front = UNBONDING_QUEUE.front(&staking_storage)?; + match front { // assuming the queue is sorted by payout_at - Some((_, payout_at, _)) if payout_at <= &block.time => { + Some((_, payout_at, _)) if payout_at <= block.time => { // remove from queue - let (delegator, _, amount) = queue.pop_front().unwrap(); + let (delegator, _, amount) = + UNBONDING_QUEUE.pop_front(&mut staking_storage)?.unwrap(); - let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); let staking_info = Self::get_staking_info(&staking_storage)?; router.execute( api, From 17d469c39a6556a177790640dda891d6d49922e4 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 7 Oct 2022 15:30:37 +0200 Subject: [PATCH 528/631] Improve coverage --- packages/multi-test/src/staking.rs | 83 ++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index d9b8e1026..270cd421b 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -131,20 +131,6 @@ impl StakeKeeper { Ok(()) } - pub fn init_stake( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - account: &Addr, - validator: &Addr, - amount: Coin, - ) -> AnyResult<()> { - let mut storage = prefixed(storage, NAMESPACE_STAKING); - - self.add_stake(api, &mut storage, block, account, validator, amount) - } - /// Add a new validator available for staking pub fn add_validator( &self, @@ -185,7 +171,7 @@ impl StakeKeeper { let validator_obj = match self.get_validator(&staking_storage, validator)? { Some(validator) => validator, - None => bail!("non-existent validator {}", validator), + None => bail!("validator {} not found", validator), }; // calculate rewards using fixed ratio let shares = match STAKES.load(&staking_storage, (delegator, validator)) { @@ -268,7 +254,7 @@ impl StakeKeeper { let mut validator_info = VALIDATOR_INFO .may_load(staking_storage, validator)? - .ok_or_else(|| anyhow!("validator not found"))?; + .ok_or_else(|| anyhow!("validator {} not found", validator))?; let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; @@ -452,7 +438,7 @@ impl StakeKeeper { // update stake of validator and stakers let mut validator_info = VALIDATOR_INFO .may_load(staking_storage, validator)? - .ok_or_else(|| anyhow!("validator not found"))?; + .ok_or_else(|| anyhow!("validator {} not found", validator))?; let remaining_percentage = Decimal::one() - percentage; validator_info.stake = validator_info.stake * remaining_percentage; @@ -1594,6 +1580,69 @@ mod test { assert_eq!(e.to_string(), "insufficient stake"); } + #[test] + fn denom_validation() { + let (mut test_env, validator) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + + let delegator1 = Addr::unchecked("delegator1"); + + // fund delegator1 account + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "FAKE")]) + .unwrap(); + + // try to delegate 100 to validator1 + let e = execute_stake( + &mut test_env, + delegator1.clone(), + StakingMsg::Delegate { + validator: validator.to_string(), + amount: coin(100, "FAKE"), + }, + ) + .unwrap_err(); + + assert_eq!( + e.to_string(), + "cannot delegate coins of denominator FAKE, only of TOKEN", + ); + } + + #[test] + fn cannot_slash_nonexistent() { + let (mut test_env, _) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + + let delegator1 = Addr::unchecked("delegator1"); + + // fund delegator1 account + test_env + .router + .bank + .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "FAKE")]) + .unwrap(); + + // try to delegate 100 to validator1 + let e = test_env + .router + .staking + .sudo( + &test_env.api, + &mut test_env.store, + &test_env.router, + &test_env.block, + StakingSudo::Slash { + validator: "nonexistingvaloper".to_string(), + percentage: Decimal::percent(50), + }, + ) + .unwrap_err(); + assert_eq!(e.to_string(), "validator nonexistingvaloper not found"); + } + #[test] fn query_staking() { // run all staking queries From 41b6432cfa46ad9636d21f46007608bd23ee2100 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 7 Oct 2022 16:16:14 +0200 Subject: [PATCH 529/631] Cleanup --- packages/multi-test/src/staking.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 270cd421b..7ad5fe6ad 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -383,10 +383,6 @@ impl StakeKeeper { ) -> AnyResult<()> { let amount = amount.into(); - if amount.is_zero() { - return Ok(()); - } - // update rewards for this validator Self::update_rewards(api, staking_storage, block, validator)?; @@ -942,7 +938,7 @@ mod test { fn add_get_validators() { let api = MockApi::default(); let mut store = MockStorage::new(); - let stake = StakeKeeper::new(); + let stake = StakeKeeper::default(); let block = mock_env().block; // add validator From 31a872e8bdeb6d4e6528b1d545c02dee1d8e0ed8 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 10 Oct 2022 10:27:50 +0200 Subject: [PATCH 530/631] Export StakingInfo in multi-test --- packages/multi-test/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 572c72c87..7d9ae4ff9 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -28,5 +28,5 @@ pub use crate::bank::{Bank, BankKeeper, BankSudo}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; pub use crate::module::{FailingModule, Module}; -pub use crate::staking::{DistributionKeeper, StakeKeeper, Staking, StakingSudo}; +pub use crate::staking::{DistributionKeeper, StakeKeeper, Staking, StakingInfo, StakingSudo}; pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; From 6e7380945a3eb8561f00b819790ea46ec6513981 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 10 Oct 2022 10:42:58 +0200 Subject: [PATCH 531/631] Make StakingInfo fields public --- packages/multi-test/src/staking.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 7ad5fe6ad..cd8b8432d 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -21,11 +21,11 @@ use crate::{BankSudo, Module}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct StakingInfo { /// The denominator of the staking token - bonded_denom: String, + pub bonded_denom: String, /// Time between unbonding and receiving tokens in seconds - unbonding_time: u64, + pub unbonding_time: u64, /// Interest rate per year (60 * 60 * 24 * 365 seconds) - apr: Decimal, + pub apr: Decimal, } impl Default for StakingInfo { From fc956b056daad110bab87ef60c9e363191a21657 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 10 Oct 2022 13:59:29 +0200 Subject: [PATCH 532/631] Allow delegating / undelegating zero coins --- packages/multi-test/src/staking.rs | 86 +++++++++++++++++++----------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index cd8b8432d..08a8291bc 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -337,7 +337,6 @@ impl StakeKeeper { amount: Coin, ) -> AnyResult<()> { self.validate_denom(staking_storage, &amount)?; - self.validate_nonzero(&amount)?; self.update_stake( api, staking_storage, @@ -359,7 +358,6 @@ impl StakeKeeper { amount: Coin, ) -> AnyResult<()> { self.validate_denom(staking_storage, &amount)?; - self.validate_nonzero(&amount)?; self.update_stake( api, staking_storage, @@ -465,11 +463,6 @@ impl StakeKeeper { Ok(()) } - fn validate_nonzero(&self, amount: &Coin) -> AnyResult<()> { - ensure!(!amount.amount.is_zero(), anyhow!("cannot delegate 0 coins")); - Ok(()) - } - // Asserts that the given coin has the proper denominator fn validate_denom(&self, staking_storage: &dyn Storage, amount: &Coin) -> AnyResult<()> { let staking_info = Self::get_staking_info(staking_storage)?; @@ -527,23 +520,24 @@ impl Module for StakeKeeper { amount.clone(), )?; // move money from sender account to this module (note we can controller sender here) - router.execute( - api, - storage, - block, - sender, - BankMsg::Send { - to_address: self.module_addr.to_string(), - amount: vec![amount], - } - .into(), - )?; + if !amount.amount.is_zero() { + router.execute( + api, + storage, + block, + sender, + BankMsg::Send { + to_address: self.module_addr.to_string(), + amount: vec![amount], + } + .into(), + )?; + } Ok(AppResponse { events, data: None }) } StakingMsg::Undelegate { validator, amount } => { let validator = api.addr_validate(&validator)?; self.validate_denom(&staking_storage, &amount)?; - self.validate_nonzero(&amount)?; // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 let events = vec![Event::new("unbond") @@ -639,17 +633,19 @@ impl Module for StakeKeeper { UNBONDING_QUEUE.pop_front(&mut staking_storage)?.unwrap(); let staking_info = Self::get_staking_info(&staking_storage)?; - router.execute( - api, - storage, - block, - self.module_addr.clone(), - BankMsg::Send { - to_address: delegator.into_string(), - amount: vec![coin(amount, &staking_info.bonded_denom)], - } - .into(), - )?; + if amount > 0 { + router.execute( + api, + storage, + block, + self.module_addr.clone(), + BankMsg::Send { + to_address: delegator.into_string(), + amount: vec![coin(amount, &staking_info.bonded_denom)], + } + .into(), + )?; + } } _ => break, } @@ -1639,6 +1635,36 @@ mod test { assert_eq!(e.to_string(), "validator nonexistingvaloper not found"); } + #[test] + fn zero_staking_allowed() { + let (mut test_env, validator) = + TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); + + let delegator = Addr::unchecked("delegator1"); + + // delegate 0 + execute_stake( + &mut test_env, + delegator.clone(), + StakingMsg::Delegate { + validator: validator.to_string(), + amount: coin(0, "TOKEN"), + }, + ) + .unwrap(); + + // undelegate 0 + execute_stake( + &mut test_env, + delegator, + StakingMsg::Undelegate { + validator: validator.to_string(), + amount: coin(0, "TOKEN"), + }, + ) + .unwrap(); + } + #[test] fn query_staking() { // run all staking queries From f02f3458dab573c2347743565d400709dbae91b3 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 11 Oct 2022 09:04:18 +0200 Subject: [PATCH 533/631] Apply suggestions from code review Co-authored-by: Tomasz Kurcz --- packages/multi-test/src/staking.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 08a8291bc..1dea0d279 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -75,6 +75,7 @@ impl ValidatorInfo { } const STAKING_INFO: Item = Item::new("staking_info"); +/// (staker_addr, validator_addr) -> shares const STAKES: Map<(&Addr, &Addr), Shares> = Map::new("stakes"); const VALIDATOR_MAP: Map<&Addr, Validator> = Map::new("validator_map"); /// Additional vec of validators, in case the `iterator` feature is disabled @@ -519,7 +520,7 @@ impl Module for StakeKeeper { &validator, amount.clone(), )?; - // move money from sender account to this module (note we can controller sender here) + // move money from sender account to this module (note we can control sender here) if !amount.amount.is_zero() { router.execute( api, From f1e2ee28db59caa5e49ee6d2021f5b58336bd28a Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 13 Oct 2022 12:48:21 +0200 Subject: [PATCH 534/631] Fix staking module --- packages/multi-test/src/staking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs index 1dea0d279..043838f32 100644 --- a/packages/multi-test/src/staking.rs +++ b/packages/multi-test/src/staking.rs @@ -9,12 +9,12 @@ use cosmwasm_std::{ DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, }; -use cosmwasm_storage::{prefixed, prefixed_read}; use cw_storage_plus::{Deque, Item, Map}; use serde::{Deserialize, Serialize}; use crate::app::CosmosRouter; use crate::executor::AppResponse; +use crate::prefixed_storage::{prefixed, prefixed_read}; use crate::{BankSudo, Module}; // Contains some general staking parameters From 3764a11057cbed6bf0fc736953c843b5799e9aae Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 14 Oct 2022 13:52:27 +0200 Subject: [PATCH 535/631] Set version: 0.15.2 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 12 ++++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-macro/Cargo.toml | 2 +- packages/storage-plus/Cargo.toml | 4 +-- packages/utils/Cargo.toml | 6 ++-- 21 files changed, 103 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ac166278..0a475d9d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,7 +390,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.15.1" +version = "0.15.2" dependencies = [ "anyhow", "cosmwasm-std", @@ -419,7 +419,7 @@ dependencies = [ [[package]] name = "cw-storage-macro" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-std", "serde", @@ -428,7 +428,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-std", "criterion", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -455,7 +455,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -465,7 +465,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.15.1" +version = "0.15.2" dependencies = [ "anyhow", "assert_matches", @@ -501,7 +501,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -512,7 +512,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -527,7 +527,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -549,7 +549,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -566,7 +566,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -583,7 +583,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -594,7 +594,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -612,7 +612,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -642,7 +642,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.15.1" +version = "0.15.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 3772c3c8a..9ac17a26c 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -20,16 +20,16 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw1 = { path = "../../packages/cw1", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.1", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw1 = { path = "../../packages/cw1", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.2", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.1", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.2", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 5c1f4a20a..8bf221094 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw1 = { path = "../../packages/cw1", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw1 = { path = "../../packages/cw1", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index efaddc066..5a155c463 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.15.1" +version = "0.15.2" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw1155 = { path = "../../packages/cw1155", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw1155 = { path = "../../packages/cw1155", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 573521921..ca53a7f47 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw20 = { path = "../../packages/cw20", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw20 = { path = "../../packages/cw20", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 24ce3ddaa..799afab67 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -19,12 +19,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw20 = { path = "../../packages/cw20", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw20 = { path = "../../packages/cw20", version = "0.15.2" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index ab24b2784..33fd78cad 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -19,16 +19,16 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw3 = { path = "../../packages/cw3", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw3 = { path = "../../packages/cw3", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "0.15.1" } -cw20-base = { path = "../cw20-base", version = "0.15.1", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } +cw20 = { path = "../../packages/cw20", version = "0.15.2" } +cw20-base = { path = "../cw20-base", version = "0.15.2", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 1a0229d2c..d2466fbfb 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -19,17 +19,17 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw3 = { path = "../../packages/cw3", version = "0.15.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.1", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw3 = { path = "../../packages/cw3", version = "0.15.2" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.2", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "0.15.1" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.1" } +cw4-group = { path = "../cw4-group", version = "0.15.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 51cf9ea94..a06600b0c 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw4 = { path = "../../packages/cw4", version = "0.15.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw4 = { path = "../../packages/cw4", version = "0.15.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index e454344e1..6552f9a76 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw2 = { path = "../../packages/cw2", version = "0.15.1" } -cw4 = { path = "../../packages/cw4", version = "0.15.1" } -cw20 = { path = "../../packages/cw20", version = "0.15.1" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw4 = { path = "../../packages/cw4", version = "0.15.2" } +cw20 = { path = "../../packages/cw20", version = "0.15.2" } +cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index ed3ece2a7..83ebdbf88 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw-utils = { path = "../utils", version = "0.15.1" } -cw-storage-plus = { path = "../storage-plus", version = "0.15.1" } +cw-utils = { path = "../utils", version = "0.15.2" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index d3a15e52f..e499c0999 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index a0330db3a..7cdaaf9a9 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.15.1" +version = "0.15.2" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 6863f21be..4f4be558a 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 55e51de55..6e2bbd907 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index e5f889fa8..314934f88 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.1" } +cw-utils = { path = "../../packages/utils", version = "0.15.2" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index ccbc806ec..a069b8114 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.15.1" } +cw-storage-plus = { path = "../storage-plus", version = "0.15.2" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 7a48b49c6..f91875440 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -17,8 +17,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.1" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1"} +cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2"} cosmwasm-std = { version = "1.1.0", features = ["staking"] } itertools = "0.10.1" schemars = "0.8.1" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index ce5740516..7f61f0ff7 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-macro" -version = "0.15.1" +version = "0.15.2" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" description = "Macro helpers for storage-plus" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index b170ff34b..d357533cb 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -24,7 +24,7 @@ bench = false cosmwasm-std = { version = "1.1.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.15.1", optional = true, path = "../storage-macro" } +cw-storage-macro = { version = "0.15.2", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = ["html_reports"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index dbbcb9dc7..fd049338a 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.15.1" +version = "0.15.2" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -13,12 +13,12 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw2 = { path = "../../packages/cw2", version = "0.15.1" } +cw2 = { path = "../../packages/cw2", version = "0.15.2" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.21" [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.1" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } prost = "0.9" From 84eff7fbc6b91d44867d064a7cfc14f1e3364e1e Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 14 Oct 2022 13:55:09 +0200 Subject: [PATCH 536/631] Update CHANGELOG.md --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 761849362..afb120b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,34 @@ # Changelog +## [v0.15.2](https://github.com/CosmWasm/cw-plus/tree/v0.15.2) (2022-10-14) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.1...HEAD) + +**Closed issues:** + +- Unable to run workspace-optimizer [\#828](https://github.com/CosmWasm/cw-plus/issues/828) +- Running the build command for the production-ready build for cw-20 and not only ends an error [\#821](https://github.com/CosmWasm/cw-plus/issues/821) +- Fill out missing high-level docs [\#806](https://github.com/CosmWasm/cw-plus/issues/806) +- Some multitest bindings for staking are missing such as `BondedDenom` [\#753](https://github.com/CosmWasm/cw-plus/issues/753) +- Allow burn to have a callback just like Send [\#717](https://github.com/CosmWasm/cw-plus/issues/717) +- Unable to upload cw20\_base wasm file on terra-station [\#716](https://github.com/CosmWasm/cw-plus/issues/716) +- Cannot upload to localterra with cw-storage-plus 0.12.1 [\#666](https://github.com/CosmWasm/cw-plus/issues/666) +- Is `MAX_LIMIT` a bug? [\#625](https://github.com/CosmWasm/cw-plus/issues/625) +- Add support for admin migrations to cw-multitest [\#744](https://github.com/CosmWasm/cw-plus/issues/744) + +**Merged pull requests:** + +- Remove `cosmwasm-storage` dependency [\#827](https://github.com/CosmWasm/cw-plus/pull/827) ([uint](https://github.com/uint)) +- Generic query for cw3 unification [\#826](https://github.com/CosmWasm/cw-plus/pull/826) ([hashedone](https://github.com/hashedone)) +- Remove cw1-whitelist-ng [\#825](https://github.com/CosmWasm/cw-plus/pull/825) ([uint](https://github.com/uint)) +- Deque changes [\#822](https://github.com/CosmWasm/cw-plus/pull/822) ([chipshort](https://github.com/chipshort)) +- Add missing docs [\#818](https://github.com/CosmWasm/cw-plus/pull/818) ([chipshort](https://github.com/chipshort)) +- Remove storage-plus dependency from storage-macro [\#817](https://github.com/CosmWasm/cw-plus/pull/817) ([chipshort](https://github.com/chipshort)) +- \[multi-test\] Add update and clear admin support to WasmKeeper [\#812](https://github.com/CosmWasm/cw-plus/pull/812) ([chipshort](https://github.com/chipshort)) +- Update CHANGELOG [\#811](https://github.com/CosmWasm/cw-plus/pull/811) ([uint](https://github.com/uint)) +- \[multi-test\] Add staking and distribution module [\#782](https://github.com/CosmWasm/cw-plus/pull/782) ([ueco-jb](https://github.com/ueco-jb)) +- Handle duplicate members in cw4-group create [\#702](https://github.com/CosmWasm/cw-plus/pull/702) ([codehans](https://github.com/codehans)) + ## [v0.15.1](https://github.com/CosmWasm/cw-plus/tree/v0.15.1) (2022-09-27) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.0...v0.15.1) From cc6c45559329194e73ec59dbdc56142a4ddd0e83 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 17 Oct 2022 10:19:37 +0200 Subject: [PATCH 537/631] Set version: 0.16.0 --- Cargo.lock | 40 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 14 ++++----- contracts/cw1-whitelist/Cargo.toml | 12 ++++---- contracts/cw1155-base/Cargo.toml | 10 +++---- contracts/cw20-base/Cargo.toml | 12 ++++---- contracts/cw20-ics20/Cargo.toml | 12 ++++---- contracts/cw3-fixed-multisig/Cargo.toml | 16 +++++----- contracts/cw3-flex-multisig/Cargo.toml | 18 +++++------ contracts/cw4-group/Cargo.toml | 12 ++++---- contracts/cw4-stake/Cargo.toml | 14 ++++----- packages/controllers/Cargo.toml | 6 ++-- packages/cw1/Cargo.toml | 2 +- packages/cw1155/Cargo.toml | 4 +-- packages/cw2/Cargo.toml | 4 +-- packages/cw20/Cargo.toml | 4 +-- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 4 +-- packages/multi-test/Cargo.toml | 6 ++-- packages/storage-macro/Cargo.toml | 2 +- packages/storage-plus/Cargo.toml | 4 +-- packages/utils/Cargo.toml | 6 ++-- 21 files changed, 103 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a475d9d2..635c6e731 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,7 +390,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.15.2" +version = "0.16.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -419,7 +419,7 @@ dependencies = [ [[package]] name = "cw-storage-macro" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-std", "serde", @@ -428,7 +428,7 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-std", "criterion", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -455,7 +455,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -465,7 +465,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.15.2" +version = "0.16.0" dependencies = [ "anyhow", "assert_matches", @@ -501,7 +501,7 @@ dependencies = [ [[package]] name = "cw1155" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -512,7 +512,7 @@ dependencies = [ [[package]] name = "cw1155-base" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -527,7 +527,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -549,7 +549,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -566,7 +566,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -583,7 +583,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -594,7 +594,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -612,7 +612,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -642,7 +642,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.15.2" +version = "0.16.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 9ac17a26c..3a7220b07 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -20,16 +20,16 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw1 = { path = "../../packages/cw1", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.2", features = ["library"] } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw1 = { path = "../../packages/cw1", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.16.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "0.15.2", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "0.16.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 8bf221094..c459010a6 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementation of an proxy contract using a whitelist" @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw1 = { path = "../../packages/cw1", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw1 = { path = "../../packages/cw1", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 5a155c463..20176bfb4 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155-base" -version = "0.15.2" +version = "0.16.0" authors = ["Huang Yi "] edition = "2018" description = "Basic implementation of a CosmWasm-1155 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw1155 = { path = "../../packages/cw1155", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw1155 = { path = "../../packages/cw1155", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index ca53a7f47..7d1b2420f 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw20 = { path = "../../packages/cw20", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 799afab67..b86a0997b 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -19,12 +19,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw20 = { path = "../../packages/cw20", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw20 = { path = "../../packages/cw20", version = "0.16.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 33fd78cad..65c15a568 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with an fixed group multisig" @@ -19,16 +19,16 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw3 = { path = "../../packages/cw3", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw3 = { path = "../../packages/cw3", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "0.15.2" } -cw20-base = { path = "../cw20-base", version = "0.15.2", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } +cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw20-base = { path = "../cw20-base", version = "0.16.0", features = ["library"] } +cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index d2466fbfb..655b1baf0 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -19,17 +19,17 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw3 = { path = "../../packages/cw3", version = "0.15.2" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.15.2", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw3 = { path = "../../packages/cw3", version = "0.16.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.16.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "0.15.2" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.15.2" } +cw4-group = { path = "../cw4-group", version = "0.16.0" } +cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index a06600b0c..27ef51a15 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Simple cw4 implementation of group membership controlled by admin " @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw4 = { path = "../../packages/cw4", version = "0.15.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw4 = { path = "../../packages/cw4", version = "0.16.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 6552f9a76..7f520a98a 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "CW4 implementation of group based on staked tokens" @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw2 = { path = "../../packages/cw2", version = "0.15.2" } -cw4 = { path = "../../packages/cw4", version = "0.15.2" } -cw20 = { path = "../../packages/cw20", version = "0.15.2" } -cw-controllers = { path = "../../packages/controllers", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw4 = { path = "../../packages/cw4", version = "0.16.0" } +cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 83ebdbf88..89e29ad25 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Common controllers we can reuse in many contracts" @@ -13,8 +13,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw-utils = { path = "../utils", version = "0.15.2" } -cw-storage-plus = { path = "../storage-plus", version = "0.15.2" } +cw-utils = { path = "../utils", version = "0.16.0" } +cw-storage-plus = { path = "../storage-plus", version = "0.16.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index e499c0999..35209202c 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index 7cdaaf9a9..f85a1e8df 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1155" -version = "0.15.2" +version = "0.16.0" authors = ["Huang Yi "] edition = "2018" description = "Definition and types for the CosmWasm-1155 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 4f4be558a..5104c2ed3 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-2 interface" @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 6e2bbd907..d76d05947 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Definition and types for the CosmWasm-20 interface" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 314934f88..777f6a0d8 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.2" } +cw-utils = { path = "../../packages/utils", version = "0.16.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index a069b8114..b0ac9b129 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "CosmWasm-4 Interface: Groups Members" @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.15.2" } +cw-storage-plus = { path = "../storage-plus", version = "0.16.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index f91875440..3fee94ea5 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-multi-test" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Test helpers for multi-contract interactions" @@ -17,8 +17,8 @@ staking = ["cosmwasm-std/staking"] backtrace = ["anyhow/backtrace"] [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.15.2" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2"} +cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0"} cosmwasm-std = { version = "1.1.0", features = ["staking"] } itertools = "0.10.1" schemars = "0.8.1" diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml index 7f61f0ff7..39eceef0c 100644 --- a/packages/storage-macro/Cargo.toml +++ b/packages/storage-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-macro" -version = "0.15.2" +version = "0.16.0" authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] edition = "2018" description = "Macro helpers for storage-plus" diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml index d357533cb..2855094c2 100644 --- a/packages/storage-plus/Cargo.toml +++ b/packages/storage-plus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-storage-plus" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Enhanced storage engines" @@ -24,7 +24,7 @@ bench = false cosmwasm-std = { version = "1.1.0", default-features = false } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.15.2", optional = true, path = "../storage-macro" } +cw-storage-macro = { version = "0.16.0", optional = true, path = "../storage-macro" } [dev-dependencies] criterion = { version = "0.3", features = ["html_reports"] } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index fd049338a..3611a9c26 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-utils" -version = "0.15.2" +version = "0.16.0" authors = ["Ethan Frey "] edition = "2018" description = "Common helpers for other cw specs" @@ -13,12 +13,12 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" -cw2 = { path = "../../packages/cw2", version = "0.15.2" } +cw2 = { path = "../../packages/cw2", version = "0.16.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.21" [dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.15.2" } +cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } prost = "0.9" From 1dd2a5357b944d26f1ebbaf14c345bbf61cb5288 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 17 Oct 2022 10:21:46 +0200 Subject: [PATCH 538/631] Update CHANGELOG to 0.16.0 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afb120b09..090cdcad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [v0.15.2](https://github.com/CosmWasm/cw-plus/tree/v0.15.2) (2022-10-14) +## [v0.16.0](https://github.com/CosmWasm/cw-plus/tree/v0.16.0) (2022-10-14) -[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.1...HEAD) +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.1...v0.16.0) **Closed issues:** From cc73e9c3e67ff0d6ffd4d4cef36fb82f79482e08 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 18 Oct 2022 22:24:22 +0200 Subject: [PATCH 539/631] Remove storage-plus, multi-test and utils --- Cargo.lock | 632 +--- contracts/cw1-subkeys/Cargo.toml | 4 +- contracts/cw1-whitelist/Cargo.toml | 6 +- contracts/cw1155-base/Cargo.toml | 4 +- contracts/cw20-base/Cargo.toml | 6 +- contracts/cw20-ics20/Cargo.toml | 4 +- contracts/cw3-fixed-multisig/Cargo.toml | 6 +- contracts/cw3-flex-multisig/Cargo.toml | 6 +- contracts/cw4-group/Cargo.toml | 4 +- contracts/cw4-stake/Cargo.toml | 4 +- packages/controllers/Cargo.toml | 8 +- packages/cw1155/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 8 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 2 +- packages/cw4/Cargo.toml | 2 +- packages/multi-test/Cargo.toml | 29 - packages/multi-test/DESIGN.md | 247 -- packages/multi-test/MIGRATING.md | 25 - packages/multi-test/NOTICE | 14 - packages/multi-test/README.md | 19 - packages/multi-test/clippy.toml | 1 - packages/multi-test/src/app.rs | 2804 ----------------- packages/multi-test/src/bank.rs | 473 --- packages/multi-test/src/contracts.rs | 437 --- packages/multi-test/src/custom_handler.rs | 93 - packages/multi-test/src/error.rs | 46 - packages/multi-test/src/executor.rs | 150 - packages/multi-test/src/lib.rs | 32 - packages/multi-test/src/module.rs | 115 - packages/multi-test/src/prefixed_storage.rs | 185 -- .../src/prefixed_storage/length_prefixed.rs | 176 -- .../src/prefixed_storage/namespace_helpers.rs | 220 -- packages/multi-test/src/staking.rs | 1809 ----------- packages/multi-test/src/test_helpers.rs | 20 - .../multi-test/src/test_helpers/contracts.rs | 8 - .../src/test_helpers/contracts/caller.rs | 40 - .../src/test_helpers/contracts/echo.rs | 140 - .../src/test_helpers/contracts/error.rs | 49 - .../src/test_helpers/contracts/hackatom.rs | 91 - .../src/test_helpers/contracts/payout.rs | 90 - .../src/test_helpers/contracts/reflect.rs | 72 - packages/multi-test/src/transactions.rs | 589 ---- packages/multi-test/src/wasm.rs | 1522 --------- packages/storage-macro/Cargo.toml | 20 - packages/storage-macro/NOTICE | 14 - packages/storage-macro/README.md | 22 - packages/storage-macro/src/lib.rs | 44 - packages/storage-plus/Cargo.toml | 35 - packages/storage-plus/NOTICE | 14 - packages/storage-plus/README.md | 702 ----- packages/storage-plus/benches/main.rs | 161 - packages/storage-plus/src/bound.rs | 184 -- packages/storage-plus/src/de.rs | 268 -- packages/storage-plus/src/deque.rs | 627 ---- packages/storage-plus/src/endian.rs | 58 - packages/storage-plus/src/helpers.rs | 194 -- packages/storage-plus/src/indexed_map.rs | 1735 ---------- packages/storage-plus/src/indexed_snapshot.rs | 1224 ------- packages/storage-plus/src/indexes/mod.rs | 38 - packages/storage-plus/src/indexes/multi.rs | 346 -- packages/storage-plus/src/indexes/unique.rs | 257 -- packages/storage-plus/src/int_key.rs | 130 - packages/storage-plus/src/item.rs | 319 -- packages/storage-plus/src/iter_helpers.rs | 222 -- packages/storage-plus/src/keys.rs | 512 --- packages/storage-plus/src/lib.rs | 87 - packages/storage-plus/src/map.rs | 1580 ---------- packages/storage-plus/src/path.rs | 96 - packages/storage-plus/src/prefix.rs | 441 --- packages/storage-plus/src/snapshot/item.rs | 325 -- packages/storage-plus/src/snapshot/map.rs | 644 ---- packages/storage-plus/src/snapshot/mod.rs | 392 --- packages/storage-plus/tests/index_list.rs | 76 - packages/utils/Cargo.toml | 24 - packages/utils/NOTICE | 14 - packages/utils/README.md | 7 - packages/utils/src/balance.rs | 319 -- packages/utils/src/event.rs | 7 - packages/utils/src/expiration.rs | 237 -- packages/utils/src/lib.rs | 34 - packages/utils/src/migrate.rs | 100 - packages/utils/src/pagination.rs | 115 - packages/utils/src/parse_reply.rs | 528 ---- packages/utils/src/payment.rs | 136 - packages/utils/src/scheduled.rs | 115 - packages/utils/src/threshold.rs | 337 -- 87 files changed, 64 insertions(+), 22872 deletions(-) delete mode 100644 packages/multi-test/Cargo.toml delete mode 100644 packages/multi-test/DESIGN.md delete mode 100644 packages/multi-test/MIGRATING.md delete mode 100644 packages/multi-test/NOTICE delete mode 100644 packages/multi-test/README.md delete mode 100644 packages/multi-test/clippy.toml delete mode 100644 packages/multi-test/src/app.rs delete mode 100644 packages/multi-test/src/bank.rs delete mode 100644 packages/multi-test/src/contracts.rs delete mode 100644 packages/multi-test/src/custom_handler.rs delete mode 100644 packages/multi-test/src/error.rs delete mode 100644 packages/multi-test/src/executor.rs delete mode 100644 packages/multi-test/src/lib.rs delete mode 100644 packages/multi-test/src/module.rs delete mode 100644 packages/multi-test/src/prefixed_storage.rs delete mode 100644 packages/multi-test/src/prefixed_storage/length_prefixed.rs delete mode 100644 packages/multi-test/src/prefixed_storage/namespace_helpers.rs delete mode 100644 packages/multi-test/src/staking.rs delete mode 100644 packages/multi-test/src/test_helpers.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/caller.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/echo.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/error.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/hackatom.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/payout.rs delete mode 100644 packages/multi-test/src/test_helpers/contracts/reflect.rs delete mode 100644 packages/multi-test/src/transactions.rs delete mode 100644 packages/multi-test/src/wasm.rs delete mode 100644 packages/storage-macro/Cargo.toml delete mode 100644 packages/storage-macro/NOTICE delete mode 100644 packages/storage-macro/README.md delete mode 100644 packages/storage-macro/src/lib.rs delete mode 100644 packages/storage-plus/Cargo.toml delete mode 100644 packages/storage-plus/NOTICE delete mode 100644 packages/storage-plus/README.md delete mode 100644 packages/storage-plus/benches/main.rs delete mode 100644 packages/storage-plus/src/bound.rs delete mode 100644 packages/storage-plus/src/de.rs delete mode 100644 packages/storage-plus/src/deque.rs delete mode 100644 packages/storage-plus/src/endian.rs delete mode 100644 packages/storage-plus/src/helpers.rs delete mode 100644 packages/storage-plus/src/indexed_map.rs delete mode 100644 packages/storage-plus/src/indexed_snapshot.rs delete mode 100644 packages/storage-plus/src/indexes/mod.rs delete mode 100644 packages/storage-plus/src/indexes/multi.rs delete mode 100644 packages/storage-plus/src/indexes/unique.rs delete mode 100644 packages/storage-plus/src/int_key.rs delete mode 100644 packages/storage-plus/src/item.rs delete mode 100644 packages/storage-plus/src/iter_helpers.rs delete mode 100644 packages/storage-plus/src/keys.rs delete mode 100644 packages/storage-plus/src/lib.rs delete mode 100644 packages/storage-plus/src/map.rs delete mode 100644 packages/storage-plus/src/path.rs delete mode 100644 packages/storage-plus/src/prefix.rs delete mode 100644 packages/storage-plus/src/snapshot/item.rs delete mode 100644 packages/storage-plus/src/snapshot/map.rs delete mode 100644 packages/storage-plus/src/snapshot/mod.rs delete mode 100644 packages/storage-plus/tests/index_list.rs delete mode 100644 packages/utils/Cargo.toml delete mode 100644 packages/utils/NOTICE delete mode 100644 packages/utils/README.md delete mode 100644 packages/utils/src/balance.rs delete mode 100644 packages/utils/src/event.rs delete mode 100644 packages/utils/src/expiration.rs delete mode 100644 packages/utils/src/lib.rs delete mode 100644 packages/utils/src/migrate.rs delete mode 100644 packages/utils/src/pagination.rs delete mode 100644 packages/utils/src/parse_reply.rs delete mode 100644 packages/utils/src/payment.rs delete mode 100644 packages/utils/src/scheduled.rs delete mode 100644 packages/utils/src/threshold.rs diff --git a/Cargo.lock b/Cargo.lock index 635c6e731..3527aa4c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,29 +2,11 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "anyhow" version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" -dependencies = [ - "backtrace", -] [[package]] name = "assert_matches" @@ -32,38 +14,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base16ct" version = "0.1.1" @@ -82,12 +32,6 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "block-buffer" version = "0.9.0" @@ -106,24 +50,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" - [[package]] name = "byteorder" version = "1.4.3" @@ -136,35 +62,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - [[package]] name = "const-oid" version = "0.9.0" @@ -244,87 +147,6 @@ dependencies = [ "libc", ] -[[package]] -name = "criterion" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -353,28 +175,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -404,6 +204,8 @@ dependencies = [ [[package]] name = "cw-multi-test" version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7192aec80d0c01a0e5941392eea7e2b7e212ee74ca7f430bfdc899420c055ef6" dependencies = [ "anyhow", "cosmwasm-std", @@ -417,23 +219,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw-storage-macro" -version = "0.16.0" -dependencies = [ - "cosmwasm-std", - "serde", - "syn", -] - [[package]] name = "cw-storage-plus" version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" dependencies = [ "cosmwasm-std", - "criterion", - "cw-storage-macro", - "rand", "schemars", "serde", ] @@ -441,12 +233,12 @@ dependencies = [ [[package]] name = "cw-utils" version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw2", - "prost", + "cw2 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "semver", "serde", @@ -473,7 +265,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2", + "cw2 0.16.0", "schemars", "semver", "serde", @@ -492,7 +284,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2", + "cw2 0.16.0", "derivative", "schemars", "serde", @@ -519,7 +311,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1155", - "cw2", + "cw2 0.16.0", "schemars", "serde", "thiserror", @@ -536,6 +328,19 @@ dependencies = [ "serde", ] +[[package]] +name = "cw2" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + [[package]] name = "cw20" version = "0.16.0" @@ -556,7 +361,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw20", "schemars", "semver", @@ -573,7 +378,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw20", "schemars", "semver", @@ -601,7 +406,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw20", "cw20-base", "cw3", @@ -619,7 +424,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw3", "cw3-fixed-multisig", "cw4", @@ -649,7 +454,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw4", "schemars", "serde", @@ -665,7 +470,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2", + "cw2 0.16.0", "cw20", "cw4", "schemars", @@ -821,12 +626,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "gimli" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" - [[package]] name = "group" version = "0.12.0" @@ -838,21 +637,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hex" version = "0.4.3" @@ -877,27 +661,12 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" -[[package]] -name = "js-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "k256" version = "0.11.4" @@ -910,91 +679,12 @@ dependencies = [ "sha2 0.10.2", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -1011,40 +701,6 @@ dependencies = [ "spki", ] -[[package]] -name = "plotters" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716b4eeb6c4a1d3ecc956f75b43ec2e8e8ba80026413e70a3f41fd3313d3492b" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" - -[[package]] -name = "plotters-svg" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - [[package]] name = "proc-macro2" version = "1.0.43" @@ -1086,27 +742,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - [[package]] name = "rand_core" version = "0.5.1" @@ -1125,51 +760,6 @@ dependencies = [ "getrandom 0.2.7", ] -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - -[[package]] -name = "regex-syntax" -version = "0.6.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" - [[package]] name = "rfc6979" version = "0.3.0" @@ -1181,27 +771,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - [[package]] name = "ryu" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schemars" version = "0.8.10" @@ -1226,12 +801,6 @@ dependencies = [ "syn", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "sec1" version = "0.3.0" @@ -1270,16 +839,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.144" @@ -1308,7 +867,7 @@ version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ - "itoa 1.0.3", + "itoa", "ryu", "serde", ] @@ -1380,15 +939,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.32" @@ -1409,16 +959,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "typenum" version = "1.15.0" @@ -1443,29 +983,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -1478,101 +1001,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" - -[[package]] -name = "web-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "zeroize" version = "1.5.7" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 3a7220b07..a2ea8749f 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -20,12 +20,12 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw1 = { path = "../../packages/cw1", version = "0.16.0" } cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "0.16.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index c459010a6..34dd9d53f 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw1 = { path = "../../packages/cw1", version = "0.16.0" } cw2 = { path = "../../packages/cw2", version = "0.16.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } +cw-multi-test = "0.16.0" derivative = "2" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml index 20176bfb4..1519faf63 100644 --- a/contracts/cw1155-base/Cargo.toml +++ b/contracts/cw1155-base/Cargo.toml @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw1155 = { path = "../../packages/cw1155", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 7d1b2420f..bc1683b4c 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw20 = { path = "../../packages/cw20", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } +cw-multi-test = "0.16.0" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index b86a0997b..9b58330b5 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -19,11 +19,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw20 = { path = "../../packages/cw20", version = "0.16.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } schemars = "0.8.1" semver = "1" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 65c15a568..f9ab43376 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw3 = { path = "../../packages/cw3", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,4 +31,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cw20 = { path = "../../packages/cw20", version = "0.16.0" } cw20-base = { path = "../cw20-base", version = "0.16.0", features = ["library"] } -cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } +cw-multi-test = "0.16.0" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 655b1baf0..291f5e51c 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -19,12 +19,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw3 = { path = "../../packages/cw3", version = "0.16.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.16.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -32,4 +32,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cw4-group = { path = "../cw4-group", version = "0.16.0" } -cw-multi-test = { path = "../../packages/multi-test", version = "0.16.0" } +cw-multi-test = "0.16.0" diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 27ef51a15..dba3b7f54 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw4 = { path = "../../packages/cw4", version = "0.16.0" } cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 7f520a98a..af8e1f734 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw4 = { path = "../../packages/cw4", version = "0.16.0" } cw20 = { path = "../../packages/cw20", version = "0.16.0" } cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 89e29ad25..e7083ed75 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -11,10 +11,10 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -cw-utils = { path = "../utils", version = "0.16.0" } -cw-storage-plus = { path = "../storage-plus", version = "0.16.0" } +cosmwasm-schema = "1.0.0" +cosmwasm-std = "1.0.0" +cw-utils = "0.16.0" +cw-storage-plus = "0.16.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml index f85a1e8df..784b5f4c9 100644 --- a/packages/cw1155/Cargo.toml +++ b/packages/cw1155/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cosmwasm-schema = "1.1.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 5104c2ed3..feab0a89b 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -9,8 +9,8 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.1.0" -cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } +cosmwasm-schema = "1.0.0" +cosmwasm-std = { version = "1.0.0", default-features = false } +cw-storage-plus = "0.16.0" schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +serde = { version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index d76d05947..fe912af57 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 777f6a0d8..4c21b571f 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = { path = "../../packages/utils", version = "0.16.0" } +cw-utils = "0.16.0" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index b0ac9b129..adb1ddaed 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = { path = "../storage-plus", version = "0.16.0" } +cw-storage-plus = "0.16.0" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml deleted file mode 100644 index 3fee94ea5..000000000 --- a/packages/multi-test/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "cw-multi-test" -version = "0.16.0" -authors = ["Ethan Frey "] -edition = "2018" -description = "Test helpers for multi-contract interactions" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[features] -default = ["iterator", "staking"] -iterator = ["cosmwasm-std/iterator"] -stargate = ["cosmwasm-std/stargate"] -staking = ["cosmwasm-std/staking"] -backtrace = ["anyhow/backtrace"] - -[dependencies] -cw-utils = { path = "../../packages/utils", version = "0.16.0" } -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0"} -cosmwasm-std = { version = "1.1.0", features = ["staking"] } -itertools = "0.10.1" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -prost = "0.9" -anyhow = "1" -thiserror = "1" -derivative = "2" diff --git a/packages/multi-test/DESIGN.md b/packages/multi-test/DESIGN.md deleted file mode 100644 index be070ccba..000000000 --- a/packages/multi-test/DESIGN.md +++ /dev/null @@ -1,247 +0,0 @@ -# Multitest Design - -Multitest is a design to simulate a blockchain environment in pure Rust. -This allows us to run unit tests that involve contract -> contract, -and contract -> bank interactions. This is not intended to be a full blockchain app -but to simulate the Cosmos SDK x/wasm module close enough to gain confidence in -multi-contract deployements before testing them on a live blockchain. - -This explains some of the design for those who want to use the API, as well as those -who want to look under the hood. - -## Key APIs - -### App - -The main entry point to the system is called `App`, which represents a blockchain app. -It maintains an idea of block height and time, which you can update to simulate multiple -blocks. You can use `app.update_block(next_block)` to increment timestamp by 5s and height by 1 -(simulating a new block) or you can write any other mutator to advance more. - -It exposes an entry point `App.execute` that allows us to execute any `CosmosMsg` -and it wraps it as an atomic transaction. That is, only if `execute` returns success, will the state -be committed. It returns the data and a list of Events on successful execution or an `Err(String)` -on error. There are some helper methods tied to the `Executor` trait that create the `CosmosMsg` for -you to provide a less verbose API. `instantiate_contract`,`execute_contract`, and `send_tokens` are exposed -for your convenience in writing tests. Each execute one `CosmosMsg` atomically as if it was submitted by a user. -(You can also use `execute_multi` if you wish to run multiple message together that revert all state if any fail). - -The other key entry point to `App` is the `Querier` interface that it implements. In particular, you -can use `App.wrap()` to get a `QuerierWrapper`, which provides all kinds of nice APIs to query the -blockchain, like `all_balances` and `query_wasm_smart`. Putting this together, you have one `Storage` wrapped -into an application, where you can execute contracts and bank, query them easily, and update the current -`BlockInfo`, in an API that is not very verbose or cumbersome. Under the hood it will process all messages -returned from contracts, move "bank" tokens and call into other contracts. - -You can create an App for use in your testcode like: - -```rust -fn mock_app() -> App { - let env = mock_env(); - let api = Box::new(MockApi::default()); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, Box::new(MockStorage::new())) -} -``` - -Inside App, it maintains the root `Storage`, and the `BlockInfo` for the current block. -It also contains a `Router` (discussed below), which can process any `CosmosMsg` variant -by passing it to the proper "Keeper". - -Note: This properly handles submessages and reply blocks. - -Note: While the API currently supports custom messages, we don't currently have a way to handle/process them. - -### Contracts - -Before you can call contracts, you must `instantiate` them. And to instantiate them, you need a `code_id`. -In `wasmd`, this `code_id` points to some stored Wasm code that is then run. In multitest, we use it to -point to a `Box` that should be run. That is, you need to implement the `Contract` trait -and then add the contract to the app via `app.store_code(my_contract)`. - -The `Contract` trait defines the major entry points to any CosmWasm contract: `execute`, `instantiate`, `query`, -`sudo`, and `reply` (for submessages). Migration and IBC are currently not supported. - -In order to easily implement `Contract` from some existing contract code, we use the `ContractWrapper` struct, -which takes some function pointers and combines them. You can look in `test_helpers.rs` for some examples -or how to do so (and useful mocks for some test cases). Here is an example of wrapping a CosmWasm contract into -a `Contract` trait to add to an `App`: - -```rust -use cw20_escrow::contract::{ execute, instantiate, query }; - -pub fn contract_escrow() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query); - Box::new(contract) -} -``` - -If you are not using custom messages in your contract, you can just use `dyn Contract`. - -### Examples - -The best intro is most likely `integration.rs` in `cw20-escrow`, which shows sending and releasing native tokens in -an escrow, as well as sending and releasing cw20 tokens. The first one updates the global bank ledger, the second -actually shows how we can test orchestrating multiple contracts. - -## Implementation - -Besides the `App` and `Contract` interfaces which are the primary means with interacting with this module, -there are a number of components that need to be understood if you wish to extend the module (say, adding -a MockStaking module to handle `CosmosMsg::Staking` and `QueryRequest::Staking` calls). - -### StorageTransaction - -Since much of the logic, both on the app side, as well as in submessages, relies on rolling back any changes -if there is an error, we make heavy use of `StorageTransaction` under the hood. It takes a `&Storage` -reference and produces `&mut Storage` that can be written too. Notably, we can still query the original -(snapshot) storage while writing (which is very useful for the `Querier` interface for contracts). - -You can drop the `StorageTransaction` causing the changes to be rolled back (well, never committed), -or on success, you can commit it to the underlying storage. Note that there may be multiple levels -or `StorageTransaction` wrappers above the root (App) storage. Here is an example of using it, -that should make the concepts clear: - -```rust -// execute in cache -let mut cache = StorageTransaction::new(storage); -// Note that we *could* query the original `storage` while `cache` is live -let res = router.execute(&mut cache, block, contract.clone(), msg.msg); -if res.is_ok() { - cache.prepare().commit(storage); -} -``` - -### Modules - -There is only one root Storage, stored inside `App`. This is wrapped into a transaction, and then passed down -to other functions to work with. The code that modifies the Storage is divided into "Modules" much like the -CosmosSDK. Here, we plan to divide logic into one "module" for every `CosmosMsg` variant. `Bank` handles `BankMsg` -and `BankQuery`, `Wasm` handles `WasmMsg` and `WasmQuery`, etc. - -Each module produces a soon-to-be standardized interface to interact with. It exposes `execute` and `query` support -as well as some "admin" methods that cannot be called by users but are needed for testcase setup. I am working on a -design to make these "admin" methods more extensible as well. If you look at the two existing modules, you can -see the great similarity in `query` and `execute`, such that we could consider making a `Module` trait. - -```rust -pub trait Wasm -where - C: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - /// Handles all WasmQuery requests - fn query( - &self, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - request: WasmQuery, - ) -> Result; - - /// Handles all WasmMsg messages - fn execute( - &self, - storage: &mut dyn Storage, - router: &Router, - block: &BlockInfo, - sender: Addr, - msg: WasmMsg, - ) -> Result; - - // Add a new contract. Must be done on the base object, when no contracts running - fn store_code(&mut self, code: Box>) -> usize; - - /// Admin interface, cannot be called via CosmosMsg - fn sudo( - &self, - contract_addr: Addr, - storage: &mut dyn Storage, - router: &Router, - block: &BlockInfo, - msg: Vec, - ) -> Result; -} -``` - -```rust -/// Bank is a minimal contract-like interface that implements a bank module -/// It is initialized outside of the trait -pub trait Bank { - fn execute( - &self, - storage: &mut dyn Storage, - sender: Addr, - msg: BankMsg, - ) -> Result; - - fn query(&self, storage: &dyn Storage, request: BankQuery) -> Result; - - // Admin interface - fn init_balance( - &self, - storage: &mut dyn Storage, - account: &Addr, - amount: Vec, - ) -> Result<(), String>; -} -``` - -These traits should capture all public interactions with the module ("Keeper interface" if you come from -Cosmos SDK terminology). All other methods on the implementations should be private (or at least not exposed -outside of the multitest crate). - -### Router - -The `Router` groups all Modules in the system into one "macro-module" that can handle any `CosmosMsg`. -While `Bank` handles `BankMsg`, and `Wasm` handles `WasmMsg`, we need to combine them into a larger whole -to process them messages from `App`. This is the concept of the `Router`. If you look at the -`execute` method, you see it is quite simple: - -```rust -impl Router { - pub fn execute( - &self, - storage: &mut dyn Storage, - block: &BlockInfo, - sender: Addr, - msg: CosmosMsg, - ) -> Result { - match msg { - CosmosMsg::Wasm(msg) => self.wasm.execute(storage, &self, block, sender, msg), - // FIXME: we could pass in unused router and block for consistency - CosmosMsg::Bank(msg) => self.bank.execute(storage, sender, msg), - _ => unimplemented!(), - } - } -} -``` - -Note that the only way one module can call or query another module is by dispatching messages via the `Router`. -This allows us to implement an independent `Wasm` in a way that it can process `SubMsg` that call into `Bank`. -You can see an example of that in WasmKeeper.send, where it moves bank tokens from one account to another: - -```rust -impl WasmKeeper { - fn send>( - &self, - storage: &mut dyn Storage, - router: &Router, - block: &BlockInfo, - sender: T, - recipient: String, - amount: &[Coin], - ) -> Result { - if !amount.is_empty() { - let msg = BankMsg::Send { - to_address: recipient, - amount: amount.to_vec(), - }; - let res = router.execute(storage, block, sender.into(), msg.into())?; - Ok(res) - } else { - Ok(AppResponse::default()) - } - } -} -``` diff --git a/packages/multi-test/MIGRATING.md b/packages/multi-test/MIGRATING.md deleted file mode 100644 index 673e17dd9..000000000 --- a/packages/multi-test/MIGRATING.md +++ /dev/null @@ -1,25 +0,0 @@ -# Migration Tips - -Note, that we currently do not support this fully for external use. -These are some partial tips to help in upgrades. - -## 0.7 -> 0.8 - -* `SimpleBank` was renamed to `BankKeeper` -* `App::new` takes `Box` rather than a closure as the last argument. -* Your test setup will look something like this: - - ```rust - pub fn mock_app() -> App { - let env = mock_env(); - let api = Box::new(MockApi::default()); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, Box::new(MockStorage::new())) - } - ``` -* `App.set_bank_balance` was renamed to `init_bank_balance`, with the same args. -* You will want to import `cw_multi_test::Executor` in order to get access to the execution helpers - like `App.execute_contract`, and `App.instantiate_contract` -* `App.instantiate_contract` takes one additional arg: `admin: Option`. You can set it to `None` - unless you want to test migrations. diff --git a/packages/multi-test/NOTICE b/packages/multi-test/NOTICE deleted file mode 100644 index 44944a1ec..000000000 --- a/packages/multi-test/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW Multi Test: Test helpers for multi-contract interactions -Copyright (C) 2020-2021 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/multi-test/README.md b/packages/multi-test/README.md deleted file mode 100644 index b0d659b69..000000000 --- a/packages/multi-test/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Multi Test: Test helpers for multi-contract interactions - -Warning: **Alpha Software** Designed for internal use only. - -This is used for testing cw-plus contracts, we have no API -stability currently. We are working on refactoring it and will -expose a more refined version for use in other contracts. (Ideally -in cw-plus 0.9 or 0.10). - -**Use at your own risk** - -Let us run unit tests with contracts calling contracts, and calling -in and out of bank. - -This only works with contracts and bank currently. We are working -on refactoring to make it more extensible for more handlers, -including custom messages/queries as well as IBC. - - diff --git a/packages/multi-test/clippy.toml b/packages/multi-test/clippy.toml deleted file mode 100644 index 15906305c..000000000 --- a/packages/multi-test/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -too-many-arguments-threshold = 10 diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs deleted file mode 100644 index 9087cebf1..000000000 --- a/packages/multi-test/src/app.rs +++ /dev/null @@ -1,2804 +0,0 @@ -use std::fmt::{self, Debug}; -use std::marker::PhantomData; - -use anyhow::bail; -use anyhow::Result as AnyResult; -use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; -use cosmwasm_std::{ - from_slice, to_binary, Addr, Api, Binary, BlockInfo, ContractResult, CosmosMsg, CustomQuery, - Empty, Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, Storage, SystemError, - SystemResult, -}; -use schemars::JsonSchema; -use serde::de::DeserializeOwned; -use serde::Serialize; - -use crate::bank::{Bank, BankKeeper, BankSudo}; -use crate::contracts::Contract; -use crate::executor::{AppResponse, Executor}; -use crate::module::{FailingModule, Module}; -use crate::staking::{Distribution, DistributionKeeper, StakeKeeper, Staking, StakingSudo}; -use crate::transactions::transactional; -use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo}; - -pub fn next_block(block: &mut BlockInfo) { - block.time = block.time.plus_seconds(5); - block.height += 1; -} - -/// Type alias for default build `App` to make its storing simpler in typical scenario -pub type BasicApp = App< - BankKeeper, - MockApi, - MockStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, ->; - -/// Router is a persisted state. You can query this. -/// Execution generally happens on the RouterCache, which then can be atomically committed or rolled back. -/// We offer .execute() as a wrapper around cache, execute, commit/rollback process. -pub struct App< - Bank = BankKeeper, - Api = MockApi, - Storage = MockStorage, - Custom = FailingModule, - Wasm = WasmKeeper, - Staking = StakeKeeper, - Distr = DistributionKeeper, -> { - router: Router, - api: Api, - storage: Storage, - block: BlockInfo, -} - -fn no_init( - _: &mut Router, - _: &dyn Api, - _: &mut dyn Storage, -) { -} - -impl Default for BasicApp { - fn default() -> Self { - Self::new(no_init) - } -} - -impl BasicApp { - /// Creates new default `App` implementation working with Empty custom messages. - pub fn new(init_fn: F) -> Self - where - F: FnOnce( - &mut Router< - BankKeeper, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - >, - &dyn Api, - &mut dyn Storage, - ), - { - AppBuilder::new().build(init_fn) - } -} - -/// Creates new default `App` implementation working with customized exec and query messages. -/// Outside of `App` implementation to make type elision better. -pub fn custom_app(init_fn: F) -> BasicApp -where - ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: Debug + CustomQuery + DeserializeOwned + 'static, - F: FnOnce( - &mut Router< - BankKeeper, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - >, - &dyn Api, - &mut dyn Storage, - ), -{ - AppBuilder::new_custom().build(init_fn) -} - -impl Querier - for App -where - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, -{ - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - self.router - .querier(&self.api, &self.storage, &self.block) - .raw_query(bin_request) - } -} - -impl Executor - for App -where - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, -{ - fn execute( - &mut self, - sender: Addr, - msg: cosmwasm_std::CosmosMsg, - ) -> AnyResult { - let mut all = self.execute_multi(sender, vec![msg])?; - let res = all.pop().unwrap(); - Ok(res) - } -} - -/// This is essential to create a custom app with custom handler. -/// let mut app = BasicAppBuilder::::new_custom().with_custom(handler).build(); -pub type BasicAppBuilder = AppBuilder< - BankKeeper, - MockApi, - MockStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, ->; - -/// Utility to build App in stages. If particular items wont be set, defaults would be used -pub struct AppBuilder { - api: Api, - block: BlockInfo, - storage: Storage, - bank: Bank, - wasm: Wasm, - custom: Custom, - staking: Staking, - distribution: Distr, -} - -impl Default - for AppBuilder< - BankKeeper, - MockApi, - MockStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - > -{ - fn default() -> Self { - Self::new() - } -} - -impl - AppBuilder< - BankKeeper, - MockApi, - MockStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - > -{ - /// Creates builder with default components working with empty exec and query messages. - pub fn new() -> Self { - AppBuilder { - api: MockApi::default(), - block: mock_env().block, - storage: MockStorage::new(), - bank: BankKeeper::new(), - wasm: WasmKeeper::new(), - custom: FailingModule::new(), - staking: StakeKeeper::new(), - distribution: DistributionKeeper::new(), - } - } -} - -impl - AppBuilder< - BankKeeper, - MockApi, - MockStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - > -where - ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: Debug + CustomQuery + DeserializeOwned + 'static, -{ - /// Creates builder with default components designed to work with custom exec and query - /// messages. - pub fn new_custom() -> Self { - AppBuilder { - api: MockApi::default(), - block: mock_env().block, - storage: MockStorage::new(), - bank: BankKeeper::new(), - wasm: WasmKeeper::new(), - custom: FailingModule::new(), - staking: StakeKeeper::new(), - distribution: DistributionKeeper::new(), - } - } -} - -impl - AppBuilder -{ - /// Overwrites default wasm executor. - /// - /// At this point it is needed that new wasm implements some `Wasm` trait, but it doesn't need - /// to be bound to Bank or Custom yet - as those may change. The cross-components validation is - /// done on final building. - /// - /// Also it is possible to completely abandon trait bounding here which would not be bad idea, - /// however it might make the message on build creepy in many cases, so as for properly build - /// `App` we always want `Wasm` to be `Wasm`, some checks are done early. - pub fn with_wasm>( - self, - wasm: NewWasm, - ) -> AppBuilder { - let AppBuilder { - bank, - api, - storage, - custom, - block, - staking, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default bank interface - pub fn with_bank( - self, - bank: NewBank, - ) -> AppBuilder { - let AppBuilder { - wasm, - api, - storage, - custom, - block, - staking, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default api interface - pub fn with_api( - self, - api: NewApi, - ) -> AppBuilder { - let AppBuilder { - wasm, - bank, - storage, - custom, - block, - staking, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default storage interface - pub fn with_storage( - self, - storage: NewStorage, - ) -> AppBuilder { - let AppBuilder { - wasm, - api, - bank, - custom, - block, - staking, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default custom messages handler - /// - /// At this point it is needed that new custom implements some `Module` trait, but it doesn't need - /// to be bound to ExecC or QueryC yet - as those may change. The cross-components validation is - /// done on final building. - /// - /// Also it is possible to completely abandon trait bounding here which would not be bad idea, - /// however it might make the message on build creepy in many cases, so as for properly build - /// `App` we always want `Wasm` to be `Wasm`, some checks are done early. - pub fn with_custom( - self, - custom: NewCustom, - ) -> AppBuilder { - let AppBuilder { - wasm, - bank, - api, - storage, - block, - staking, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default bank interface - pub fn with_staking( - self, - staking: NewStaking, - ) -> AppBuilder { - let AppBuilder { - wasm, - api, - storage, - custom, - block, - bank, - distribution, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default bank interface - pub fn with_distribution( - self, - distribution: NewDistribution, - ) -> AppBuilder { - let AppBuilder { - wasm, - api, - storage, - custom, - block, - staking, - bank, - .. - } = self; - - AppBuilder { - api, - block, - storage, - bank, - wasm, - custom, - staking, - distribution, - } - } - - /// Overwrites default initial block - pub fn with_block(mut self, block: BlockInfo) -> Self { - self.block = block; - self - } - - /// Builds final `App`. At this point all components type have to be properly related to each - /// other. If there are some generics related compilation error make sure, that all components - /// are properly relating to each other. - pub fn build( - self, - init_fn: F, - ) -> App - where - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - WasmT: Wasm, - StakingT: Staking, - DistrT: Distribution, - F: FnOnce(&mut Router, &dyn Api, &mut dyn Storage), - { - let router = Router { - wasm: self.wasm, - bank: self.bank, - custom: self.custom, - staking: self.staking, - distribution: self.distribution, - }; - - let mut app = App { - router, - api: self.api, - block: self.block, - storage: self.storage, - }; - app.init_modules(init_fn); - app - } -} - -impl - App -where - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, -{ - pub fn init_modules(&mut self, init_fn: F) -> T - where - F: FnOnce( - &mut Router, - &dyn Api, - &mut dyn Storage, - ) -> T, - { - init_fn(&mut self.router, &self.api, &mut self.storage) - } - - pub fn read_module(&self, query_fn: F) -> T - where - F: FnOnce(&Router, &dyn Api, &dyn Storage) -> T, - { - query_fn(&self.router, &self.api, &self.storage) - } -} - -// Helper functions to call some custom WasmKeeper logic. -// They show how we can easily add such calls to other custom keepers (CustomT, StakingT, etc) -impl - App< - BankT, - ApiT, - StorageT, - CustomT, - WasmKeeper, - StakingT, - DistrT, - > -where - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, -{ - /// This registers contract code (like uploading wasm bytecode on a chain), - /// so it can later be used to instantiate a contract. - pub fn store_code(&mut self, code: Box>) -> u64 { - self.init_modules(|router, _, _| router.wasm.store_code(code) as u64) - } - - /// This allows to get `ContractData` for specific contract - pub fn contract_data(&self, address: &Addr) -> AnyResult { - self.read_module(|router, _, storage| router.wasm.load_contract(storage, address)) - } - - /// This gets a raw state dump of all key-values held by a given contract - pub fn dump_wasm_raw(&self, address: &Addr) -> Vec { - self.read_module(|router, _, storage| router.wasm.dump_wasm_raw(storage, address)) - } -} - -impl - App -where - CustomT::ExecT: std::fmt::Debug + PartialEq + Clone + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, -{ - pub fn set_block(&mut self, block: BlockInfo) { - self.block = block; - } - - // this let's use use "next block" steps that add eg. one height and 5 seconds - pub fn update_block(&mut self, action: F) { - action(&mut self.block); - } - - /// Returns a copy of the current block_info - pub fn block_info(&self) -> BlockInfo { - self.block.clone() - } - - /// Simple helper so we get access to all the QuerierWrapper helpers, - /// eg. wrap().query_wasm_smart, query_all_balances, ... - pub fn wrap(&self) -> QuerierWrapper { - QuerierWrapper::new(self) - } - - /// Runs multiple CosmosMsg in one atomic operation. - /// This will create a cache before the execution, so no state changes are persisted if any of them - /// return an error. But all writes are persisted on success. - pub fn execute_multi( - &mut self, - sender: Addr, - msgs: Vec>, - ) -> AnyResult> { - // we need to do some caching of storage here, once in the entry point: - // meaning, wrap current state, all writes go to a cache, only when execute - // returns a success do we flush it (otherwise drop it) - - let Self { - block, - router, - api, - storage, - } = self; - - transactional(&mut *storage, |write_cache, _| { - msgs.into_iter() - .map(|msg| router.execute(&*api, write_cache, block, sender.clone(), msg)) - .collect() - }) - } - - /// Call a smart contract in "sudo" mode. - /// This will create a cache before the execution, so no state changes are persisted if this - /// returns an error, but all are persisted on success. - pub fn wasm_sudo>( - &mut self, - contract_addr: U, - msg: &T, - ) -> AnyResult { - let msg = to_binary(msg)?; - - let Self { - block, - router, - api, - storage, - } = self; - - transactional(&mut *storage, |write_cache, _| { - router - .wasm - .sudo(&*api, contract_addr.into(), write_cache, router, block, msg) - }) - } - - /// Runs arbitrary SudoMsg. - /// This will create a cache before the execution, so no state changes are persisted if this - /// returns an error, but all are persisted on success. - pub fn sudo(&mut self, msg: SudoMsg) -> AnyResult { - // we need to do some caching of storage here, once in the entry point: - // meaning, wrap current state, all writes go to a cache, only when execute - // returns a success do we flush it (otherwise drop it) - let Self { - block, - router, - api, - storage, - } = self; - - transactional(&mut *storage, |write_cache, _| { - router.sudo(&*api, write_cache, block, msg) - }) - } -} - -pub struct Router { - // this can remain crate-only as all special functions are wired up to app currently - // we need to figure out another format for wasm, as some like sudo need to be called after init - pub(crate) wasm: Wasm, - // these must be pub so we can initialize them (super user) on build - pub bank: Bank, - pub custom: Custom, - pub staking: Staking, - pub distribution: Distr, -} - -impl Router -where - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - CustomT: Module, - WasmT: Wasm, - BankT: Bank, - StakingT: Staking, - DistrT: Distribution, -{ - pub fn querier<'a>( - &'a self, - api: &'a dyn Api, - storage: &'a dyn Storage, - block_info: &'a BlockInfo, - ) -> RouterQuerier<'a, CustomT::ExecT, CustomT::QueryT> { - RouterQuerier { - router: self, - api, - storage, - block_info, - } - } -} - -/// We use it to allow calling into modules from another module in sudo mode. -/// Things like gov proposals belong here. -pub enum SudoMsg { - Bank(BankSudo), - Custom(Empty), - Staking(StakingSudo), - Wasm(WasmSudo), -} - -impl From for SudoMsg { - fn from(wasm: WasmSudo) -> Self { - SudoMsg::Wasm(wasm) - } -} - -impl From for SudoMsg { - fn from(bank: BankSudo) -> Self { - SudoMsg::Bank(bank) - } -} - -impl From for SudoMsg { - fn from(staking: StakingSudo) -> Self { - SudoMsg::Staking(staking) - } -} - -pub trait CosmosRouter { - type ExecC; - type QueryC: CustomQuery; - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - sender: Addr, - msg: CosmosMsg, - ) -> AnyResult; - - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - block: &BlockInfo, - request: QueryRequest, - ) -> AnyResult; - - fn sudo( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - msg: SudoMsg, - ) -> AnyResult; -} - -impl CosmosRouter - for Router -where - CustomT::ExecT: std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - CustomT: Module, - WasmT: Wasm, - BankT: Bank, - StakingT: Staking, - DistrT: Distribution, -{ - type ExecC = CustomT::ExecT; - type QueryC = CustomT::QueryT; - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - sender: Addr, - msg: CosmosMsg, - ) -> AnyResult { - match msg { - CosmosMsg::Wasm(msg) => self.wasm.execute(api, storage, self, block, sender, msg), - CosmosMsg::Bank(msg) => self.bank.execute(api, storage, self, block, sender, msg), - CosmosMsg::Custom(msg) => self.custom.execute(api, storage, self, block, sender, msg), - CosmosMsg::Staking(msg) => self.staking.execute(api, storage, self, block, sender, msg), - CosmosMsg::Distribution(msg) => self - .distribution - .execute(api, storage, self, block, sender, msg), - _ => bail!("Cannot execute {:?}", msg), - } - } - - /// this is used by `RouterQuerier` to actual implement the `Querier` interface. - /// you most likely want to use `router.querier(storage, block).wrap()` to get a - /// QuerierWrapper to interact with - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - block: &BlockInfo, - request: QueryRequest, - ) -> AnyResult { - let querier = self.querier(api, storage, block); - match request { - QueryRequest::Wasm(req) => self.wasm.query(api, storage, &querier, block, req), - QueryRequest::Bank(req) => self.bank.query(api, storage, &querier, block, req), - QueryRequest::Custom(req) => self.custom.query(api, storage, &querier, block, req), - QueryRequest::Staking(req) => self.staking.query(api, storage, &querier, block, req), - _ => unimplemented!(), - } - } - - fn sudo( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - msg: SudoMsg, - ) -> AnyResult { - match msg { - SudoMsg::Wasm(msg) => { - self.wasm - .sudo(api, msg.contract_addr, storage, self, block, msg.msg) - } - SudoMsg::Bank(msg) => self.bank.sudo(api, storage, self, block, msg), - SudoMsg::Staking(msg) => self.staking.sudo(api, storage, self, block, msg), - SudoMsg::Custom(_) => unimplemented!(), - } - } -} - -pub struct MockRouter(PhantomData<(ExecC, QueryC)>); - -impl Default for MockRouter { - fn default() -> Self { - Self::new() - } -} - -impl MockRouter { - pub fn new() -> Self - where - QueryC: CustomQuery, - { - MockRouter(PhantomData) - } -} - -impl CosmosRouter for MockRouter -where - QueryC: CustomQuery, -{ - type ExecC = ExecC; - type QueryC = QueryC; - - fn execute( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _block: &BlockInfo, - _sender: Addr, - _msg: CosmosMsg, - ) -> AnyResult { - panic!("Cannot execute MockRouters"); - } - - fn query( - &self, - _api: &dyn Api, - _storage: &dyn Storage, - _block: &BlockInfo, - _request: QueryRequest, - ) -> AnyResult { - panic!("Cannot query MockRouters"); - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _block: &BlockInfo, - _msg: SudoMsg, - ) -> AnyResult { - panic!("Cannot sudo MockRouters"); - } -} - -pub struct RouterQuerier<'a, ExecC, QueryC> { - router: &'a dyn CosmosRouter, - api: &'a dyn Api, - storage: &'a dyn Storage, - block_info: &'a BlockInfo, -} - -impl<'a, ExecC, QueryC> RouterQuerier<'a, ExecC, QueryC> { - pub fn new( - router: &'a dyn CosmosRouter, - api: &'a dyn Api, - storage: &'a dyn Storage, - block_info: &'a BlockInfo, - ) -> Self { - Self { - router, - api, - storage, - block_info, - } - } -} - -impl<'a, ExecC, QueryC> Querier for RouterQuerier<'a, ExecC, QueryC> -where - ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, -{ - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - let request: QueryRequest = match from_slice(bin_request) { - Ok(v) => v, - Err(e) => { - return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {}", e), - request: bin_request.into(), - }) - } - }; - let contract_result: ContractResult = self - .router - .query(self.api, self.storage, self.block_info, request) - .into(); - SystemResult::Ok(contract_result) - } -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::MockQuerier; - use cosmwasm_std::{ - coin, coins, to_binary, AllBalanceResponse, Attribute, BankMsg, BankQuery, Coin, Event, - OverflowError, OverflowOperation, Reply, StdError, StdResult, SubMsg, WasmMsg, - }; - - use crate::error::Error; - use crate::test_helpers::contracts::{caller, echo, error, hackatom, payout, reflect}; - use crate::test_helpers::{CustomMsg, EmptyMsg}; - use crate::transactions::StorageTransaction; - - fn get_balance( - app: &App, - addr: &Addr, - ) -> Vec - where - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - { - app.wrap().query_all_balances(addr).unwrap() - } - - #[test] - fn update_block() { - let mut app = App::default(); - - let BlockInfo { time, height, .. } = app.block; - app.update_block(next_block); - - assert_eq!(time.plus_seconds(5), app.block.time); - assert_eq!(height + 1, app.block.height); - } - - #[test] - fn send_tokens() { - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("receiver"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - let rcpt_funds = vec![coin(5, "btc")]; - - let mut app = App::new(|router, _, storage| { - // initialization moved to App construction - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - router - .bank - .init_balance(storage, &rcpt, rcpt_funds) - .unwrap(); - }); - - // send both tokens - let to_send = vec![coin(30, "eth"), coin(5, "btc")]; - let msg: cosmwasm_std::CosmosMsg = BankMsg::Send { - to_address: rcpt.clone().into(), - amount: to_send, - } - .into(); - app.execute(owner.clone(), msg.clone()).unwrap(); - let rich = get_balance(&app, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - let poor = get_balance(&app, &rcpt); - assert_eq!(vec![coin(10, "btc"), coin(30, "eth")], poor); - - // can send from other account (but funds will be deducted from sender) - app.execute(rcpt.clone(), msg).unwrap(); - - // cannot send too much - let msg = BankMsg::Send { - to_address: rcpt.into(), - amount: coins(20, "btc"), - } - .into(); - app.execute(owner.clone(), msg).unwrap_err(); - - let rich = get_balance(&app, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - } - - #[test] - fn simple_contract() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - let mut app = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up contract - let code_id = app.store_code(payout::contract()); - let msg = payout::InstantiateMessage { - payout: coin(5, "eth"), - }; - let contract_addr = app - .instantiate_contract( - code_id, - owner.clone(), - &msg, - &coins(23, "eth"), - "Payout", - None, - ) - .unwrap(); - - let contract_data = app.contract_data(&contract_addr).unwrap(); - assert_eq!( - contract_data, - ContractData { - code_id: code_id as usize, - creator: owner.clone(), - admin: None, - label: "Payout".to_owned(), - created: app.block_info().height - } - ); - - // sender funds deducted - let sender = get_balance(&app, &owner); - assert_eq!(sender, vec![coin(20, "btc"), coin(77, "eth")]); - // get contract address, has funds - let funds = get_balance(&app, &contract_addr); - assert_eq!(funds, coins(23, "eth")); - - // create empty account - let random = Addr::unchecked("random"); - let funds = get_balance(&app, &random); - assert_eq!(funds, vec![]); - - // do one payout and see money coming in - let res = app - .execute_contract(random.clone(), contract_addr.clone(), &EmptyMsg {}, &[]) - .unwrap(); - assert_eq!(3, res.events.len()); - - // the call to payout does emit this as well as custom attributes - let payout_exec = &res.events[0]; - assert_eq!(payout_exec.ty.as_str(), "execute"); - assert_eq!(payout_exec.attributes, [("_contract_addr", &contract_addr)]); - - // next is a custom wasm event - let custom_attrs = res.custom_attrs(1); - assert_eq!(custom_attrs, [("action", "payout")]); - - // then the transfer event - let expected_transfer = Event::new("transfer") - .add_attribute("recipient", "random") - .add_attribute("sender", &contract_addr) - .add_attribute("amount", "5eth"); - assert_eq!(&expected_transfer, &res.events[2]); - - // random got cash - let funds = get_balance(&app, &random); - assert_eq!(funds, coins(5, "eth")); - // contract lost it - let funds = get_balance(&app, &contract_addr); - assert_eq!(funds, coins(18, "eth")); - } - - #[test] - fn reflect_success() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - let mut app = custom_app::(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up payout contract - let payout_id = app.store_code(payout::contract()); - let msg = payout::InstantiateMessage { - payout: coin(5, "eth"), - }; - let payout_addr = app - .instantiate_contract( - payout_id, - owner.clone(), - &msg, - &coins(23, "eth"), - "Payout", - None, - ) - .unwrap(); - - // set up reflect contract - let reflect_id = app.store_code(reflect::contract()); - let reflect_addr = app - .instantiate_contract(reflect_id, owner, &EmptyMsg {}, &[], "Reflect", None) - .unwrap(); - - // reflect account is empty - let funds = get_balance(&app, &reflect_addr); - assert_eq!(funds, vec![]); - // reflect count is 1 - let qres: payout::CountResponse = app - .wrap() - .query_wasm_smart(&reflect_addr, &reflect::QueryMsg::Count {}) - .unwrap(); - assert_eq!(0, qres.count); - - // reflecting payout message pays reflect contract - let msg = SubMsg::new(WasmMsg::Execute { - contract_addr: payout_addr.clone().into(), - msg: b"{}".into(), - funds: vec![], - }); - let msgs = reflect::Message { - messages: vec![msg], - }; - let res = app - .execute_contract(Addr::unchecked("random"), reflect_addr.clone(), &msgs, &[]) - .unwrap(); - - // ensure the attributes were relayed from the sub-message - assert_eq!(4, res.events.len(), "{:?}", res.events); - - // reflect only returns standard wasm-execute event - let ref_exec = &res.events[0]; - assert_eq!(ref_exec.ty.as_str(), "execute"); - assert_eq!(ref_exec.attributes, [("_contract_addr", &reflect_addr)]); - - // the call to payout does emit this as well as custom attributes - let payout_exec = &res.events[1]; - assert_eq!(payout_exec.ty.as_str(), "execute"); - assert_eq!(payout_exec.attributes, [("_contract_addr", &payout_addr)]); - - let payout = &res.events[2]; - assert_eq!(payout.ty.as_str(), "wasm"); - assert_eq!( - payout.attributes, - [ - ("_contract_addr", payout_addr.as_str()), - ("action", "payout") - ] - ); - - // final event is the transfer from bank - let second = &res.events[3]; - assert_eq!(second.ty.as_str(), "transfer"); - assert_eq!(3, second.attributes.len()); - assert_eq!(second.attributes[0], ("recipient", &reflect_addr)); - assert_eq!(second.attributes[1], ("sender", &payout_addr)); - assert_eq!(second.attributes[2], ("amount", "5eth")); - - // ensure transfer was executed with reflect as sender - let funds = get_balance(&app, &reflect_addr); - assert_eq!(funds, coins(5, "eth")); - - // reflect count updated - let qres: payout::CountResponse = app - .wrap() - .query_wasm_smart(&reflect_addr, &reflect::QueryMsg::Count {}) - .unwrap(); - assert_eq!(1, qres.count); - } - - #[test] - fn reflect_error() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - let mut app = custom_app::(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up reflect contract - let reflect_id = app.store_code(reflect::contract()); - let reflect_addr = app - .instantiate_contract( - reflect_id, - owner, - &EmptyMsg {}, - &coins(40, "eth"), - "Reflect", - None, - ) - .unwrap(); - - // reflect has 40 eth - let funds = get_balance(&app, &reflect_addr); - assert_eq!(funds, coins(40, "eth")); - let random = Addr::unchecked("random"); - - // sending 7 eth works - let msg = SubMsg::new(BankMsg::Send { - to_address: random.clone().into(), - amount: coins(7, "eth"), - }); - let msgs = reflect::Message { - messages: vec![msg], - }; - let res = app - .execute_contract(random.clone(), reflect_addr.clone(), &msgs, &[]) - .unwrap(); - // no wasm events as no attributes - assert_eq!(2, res.events.len()); - // standard wasm-execute event - let exec = &res.events[0]; - assert_eq!(exec.ty.as_str(), "execute"); - assert_eq!(exec.attributes, [("_contract_addr", &reflect_addr)]); - // only transfer event from bank - let transfer = &res.events[1]; - assert_eq!(transfer.ty.as_str(), "transfer"); - - // ensure random got paid - let funds = get_balance(&app, &random); - assert_eq!(funds, coins(7, "eth")); - - // reflect count should be updated to 1 - let qres: payout::CountResponse = app - .wrap() - .query_wasm_smart(&reflect_addr, &reflect::QueryMsg::Count {}) - .unwrap(); - assert_eq!(1, qres.count); - - // sending 8 eth, then 3 btc should fail both - let msg = SubMsg::new(BankMsg::Send { - to_address: random.clone().into(), - amount: coins(8, "eth"), - }); - let msg2 = SubMsg::new(BankMsg::Send { - to_address: random.clone().into(), - amount: coins(3, "btc"), - }); - let msgs = reflect::Message { - messages: vec![msg, msg2], - }; - let err = app - .execute_contract(random.clone(), reflect_addr.clone(), &msgs, &[]) - .unwrap_err(); - assert_eq!( - StdError::overflow(OverflowError::new(OverflowOperation::Sub, 0, 3)), - err.downcast().unwrap() - ); - - // first one should have been rolled-back on error (no second payment) - let funds = get_balance(&app, &random); - assert_eq!(funds, coins(7, "eth")); - - // failure should not update reflect count - let qres: payout::CountResponse = app - .wrap() - .query_wasm_smart(&reflect_addr, &reflect::QueryMsg::Count {}) - .unwrap(); - assert_eq!(1, qres.count); - } - - #[test] - fn sudo_works() { - let owner = Addr::unchecked("owner"); - let init_funds = vec![coin(100, "eth")]; - - let mut app = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - let payout_id = app.store_code(payout::contract()); - let msg = payout::InstantiateMessage { - payout: coin(5, "eth"), - }; - let payout_addr = app - .instantiate_contract(payout_id, owner, &msg, &coins(23, "eth"), "Payout", None) - .unwrap(); - - // count is 1 - let payout::CountResponse { count } = app - .wrap() - .query_wasm_smart(&payout_addr, &payout::QueryMsg::Count {}) - .unwrap(); - assert_eq!(1, count); - - // wasm_sudo call - let msg = payout::SudoMsg { set_count: 25 }; - app.wasm_sudo(payout_addr.clone(), &msg).unwrap(); - - // count is 25 - let payout::CountResponse { count } = app - .wrap() - .query_wasm_smart(&payout_addr, &payout::QueryMsg::Count {}) - .unwrap(); - assert_eq!(25, count); - - // we can do the same with sudo call - let msg = payout::SudoMsg { set_count: 49 }; - let sudo_msg = WasmSudo { - contract_addr: payout_addr.clone(), - msg: to_binary(&msg).unwrap(), - }; - app.sudo(sudo_msg.into()).unwrap(); - - let payout::CountResponse { count } = app - .wrap() - .query_wasm_smart(&payout_addr, &payout::QueryMsg::Count {}) - .unwrap(); - assert_eq!(49, count); - } - - // this demonstrates that we can mint tokens and send from other accounts via a custom module, - // as an example of ability to do privileged actions - mod custom_handler { - use super::*; - - use anyhow::{bail, Result as AnyResult}; - use cw_storage_plus::Item; - use serde::{Deserialize, Serialize}; - - use crate::Executor; - - const LOTTERY: Item = Item::new("lottery"); - const PITY: Item = Item::new("pity"); - - #[derive(Clone, std::fmt::Debug, PartialEq, JsonSchema, Serialize, Deserialize)] - struct CustomMsg { - // we mint LOTTERY tokens to this one - lucky_winner: String, - // we transfer PITY from lucky_winner to runner_up - runner_up: String, - } - - struct CustomHandler {} - - impl Module for CustomHandler { - type ExecT = CustomMsg; - type QueryT = Empty; - type SudoT = Empty; - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - _sender: Addr, - msg: Self::ExecT, - ) -> AnyResult - where - ExecC: - std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, - { - let lottery = LOTTERY.load(storage)?; - let pity = PITY.load(storage)?; - - // mint new tokens - let mint = BankSudo::Mint { - to_address: msg.lucky_winner.clone(), - amount: vec![lottery], - }; - router.sudo(api, storage, block, mint.into())?; - - // send from an arbitrary account (not the module) - let transfer = BankMsg::Send { - to_address: msg.runner_up, - amount: vec![pity], - }; - let rcpt = api.addr_validate(&msg.lucky_winner)?; - router.execute(api, storage, block, rcpt, transfer.into())?; - - Ok(AppResponse::default()) - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - _msg: Self::SudoT, - ) -> AnyResult - where - ExecC: - std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, - { - bail!("sudo not implemented for CustomHandler") - } - - fn query( - &self, - _api: &dyn Api, - _storage: &dyn Storage, - _querier: &dyn Querier, - _block: &BlockInfo, - _request: Self::QueryT, - ) -> AnyResult { - bail!("query not implemented for CustomHandler") - } - } - - impl CustomHandler { - // this is a custom initialization method - pub fn set_payout( - &self, - storage: &mut dyn Storage, - lottery: Coin, - pity: Coin, - ) -> AnyResult<()> { - LOTTERY.save(storage, &lottery)?; - PITY.save(storage, &pity)?; - Ok(()) - } - } - - // let's call this custom handler - #[test] - fn dispatches_messages() { - let winner = "winner".to_string(); - let second = "second".to_string(); - - // payments. note 54321 - 12321 = 42000 - let denom = "tix"; - let lottery = coin(54321, denom); - let bonus = coin(12321, denom); - - let mut app = BasicAppBuilder::::new_custom() - .with_custom(CustomHandler {}) - .build(|router, _, storage| { - router - .custom - .set_payout(storage, lottery.clone(), bonus.clone()) - .unwrap(); - }); - - // query that balances are empty - let start = app.wrap().query_balance(&winner, denom).unwrap(); - assert_eq!(start, coin(0, denom)); - - // trigger the custom module - let msg = CosmosMsg::Custom(CustomMsg { - lucky_winner: winner.clone(), - runner_up: second.clone(), - }); - app.execute(Addr::unchecked("anyone"), msg).unwrap(); - - // see if coins were properly added - let big_win = app.wrap().query_balance(&winner, denom).unwrap(); - assert_eq!(big_win, coin(42000, denom)); - let little_win = app.wrap().query_balance(&second, denom).unwrap(); - assert_eq!(little_win, bonus); - } - } - - #[test] - fn reflect_submessage_reply_works() { - // set personal balance - let owner = Addr::unchecked("owner"); - let random = Addr::unchecked("random"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - let mut app = custom_app::(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up reflect contract - let reflect_id = app.store_code(reflect::contract()); - let reflect_addr = app - .instantiate_contract( - reflect_id, - owner, - &EmptyMsg {}, - &coins(40, "eth"), - "Reflect", - None, - ) - .unwrap(); - - // no reply writen beforehand - let query = reflect::QueryMsg::Reply { id: 123 }; - let res: StdResult = app.wrap().query_wasm_smart(&reflect_addr, &query); - res.unwrap_err(); - - // reflect sends 7 eth, success - let msg = SubMsg::reply_always( - BankMsg::Send { - to_address: random.clone().into(), - amount: coins(7, "eth"), - }, - 123, - ); - let msgs = reflect::Message { - messages: vec![msg], - }; - let res = app - .execute_contract(random.clone(), reflect_addr.clone(), &msgs, &[]) - .unwrap(); - - // expected events: execute, transfer, reply, custom wasm (set in reply) - assert_eq!(4, res.events.len(), "{:?}", res.events); - res.assert_event(&Event::new("execute").add_attribute("_contract_addr", &reflect_addr)); - res.assert_event(&Event::new("transfer").add_attribute("amount", "7eth")); - res.assert_event( - &Event::new("reply") - .add_attribute("_contract_addr", reflect_addr.as_str()) - .add_attribute("mode", "handle_success"), - ); - res.assert_event(&Event::new("wasm-custom").add_attribute("from", "reply")); - - // ensure success was written - let res: Reply = app.wrap().query_wasm_smart(&reflect_addr, &query).unwrap(); - assert_eq!(res.id, 123); - // validate the events written in the reply blob...should just be bank transfer - let reply = res.result.unwrap(); - assert_eq!(1, reply.events.len()); - AppResponse::from(reply) - .assert_event(&Event::new("transfer").add_attribute("amount", "7eth")); - - // reflect sends 300 btc, failure, but error caught by submessage (so shows success) - let msg = SubMsg::reply_always( - BankMsg::Send { - to_address: random.clone().into(), - amount: coins(300, "btc"), - }, - 456, - ); - let msgs = reflect::Message { - messages: vec![msg], - }; - let _res = app - .execute_contract(random, reflect_addr.clone(), &msgs, &[]) - .unwrap(); - - // ensure error was written - let query = reflect::QueryMsg::Reply { id: 456 }; - let res: Reply = app.wrap().query_wasm_smart(&reflect_addr, &query).unwrap(); - assert_eq!(res.id, 456); - assert!(res.result.is_err()); - // TODO: check error? - } - - fn query_router( - router: &Router, - api: &dyn Api, - storage: &dyn Storage, - rcpt: &Addr, - ) -> Vec - where - CustomT::ExecT: Clone + fmt::Debug + PartialEq + JsonSchema, - CustomT::QueryT: CustomQuery + DeserializeOwned, - WasmT: Wasm, - BankT: Bank, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, - { - let query = BankQuery::AllBalances { - address: rcpt.into(), - }; - let block = mock_env().block; - let querier: MockQuerier = MockQuerier::new(&[]); - let res = router - .bank - .query(api, storage, &querier, &block, query) - .unwrap(); - let val: AllBalanceResponse = from_slice(&res).unwrap(); - val.amount - } - - fn query_app( - app: &App, - rcpt: &Addr, - ) -> Vec - where - CustomT::ExecT: - std::fmt::Debug + PartialEq + Clone + JsonSchema + DeserializeOwned + 'static, - CustomT::QueryT: CustomQuery + DeserializeOwned + 'static, - WasmT: Wasm, - BankT: Bank, - ApiT: Api, - StorageT: Storage, - CustomT: Module, - StakingT: Staking, - DistrT: Distribution, - { - let query = BankQuery::AllBalances { - address: rcpt.into(), - } - .into(); - let val: AllBalanceResponse = app.wrap().query(&query).unwrap(); - val.amount - } - - #[test] - fn multi_level_bank_cache() { - // set personal balance - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("recipient"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - let mut app = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // cache 1 - send some tokens - let mut cache = StorageTransaction::new(&app.storage); - let msg = BankMsg::Send { - to_address: rcpt.clone().into(), - amount: coins(25, "eth"), - }; - app.router - .execute(&app.api, &mut cache, &app.block, owner.clone(), msg.into()) - .unwrap(); - - // shows up in cache - let cached_rcpt = query_router(&app.router, &app.api, &cache, &rcpt); - assert_eq!(coins(25, "eth"), cached_rcpt); - let router_rcpt = query_app(&app, &rcpt); - assert_eq!(router_rcpt, vec![]); - - // now, second level cache - transactional(&mut cache, |cache2, read| { - let msg = BankMsg::Send { - to_address: rcpt.clone().into(), - amount: coins(12, "eth"), - }; - app.router - .execute(&app.api, cache2, &app.block, owner, msg.into()) - .unwrap(); - - // shows up in 2nd cache - let cached_rcpt = query_router(&app.router, &app.api, read, &rcpt); - assert_eq!(coins(25, "eth"), cached_rcpt); - let cached2_rcpt = query_router(&app.router, &app.api, cache2, &rcpt); - assert_eq!(coins(37, "eth"), cached2_rcpt); - Ok(()) - }) - .unwrap(); - - // apply first to router - cache.prepare().commit(&mut app.storage); - - let committed = query_app(&app, &rcpt); - assert_eq!(coins(37, "eth"), committed); - } - - #[test] - fn sent_funds_properly_visible_on_execution() { - // Testing if funds on contract are properly visible on contract. - // Hackatom contract is initialized with 10btc. Then, the contract is executed, with - // additional 20btc. Then beneficiary balance is checked - expeced value is 30btc. 10btc - // would mean that sending tokens with message is not visible for this very message, and - // 20btc means, that only such just send funds are visible. - let owner = Addr::unchecked("owner"); - let beneficiary = Addr::unchecked("beneficiary"); - let init_funds = coins(30, "btc"); - - let mut app = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - let contract_id = app.store_code(hackatom::contract()); - let contract = app - .instantiate_contract( - contract_id, - owner.clone(), - &hackatom::InstantiateMsg { - beneficiary: beneficiary.as_str().to_owned(), - }, - &coins(10, "btc"), - "Hackatom", - None, - ) - .unwrap(); - - app.execute_contract( - owner.clone(), - contract.clone(), - &EmptyMsg {}, - &coins(20, "btc"), - ) - .unwrap(); - - // Check balance of all accounts to ensure no tokens where burned or created, and they are - // in correct places - assert_eq!(get_balance(&app, &owner), &[]); - assert_eq!(get_balance(&app, &contract), &[]); - assert_eq!(get_balance(&app, &beneficiary), coins(30, "btc")); - } - - #[test] - fn sent_wasm_migration_works() { - // The plan: - // create a hackatom contract with some funds - // check admin set properly - // check beneficiary set properly - // migrate fails if not admin - // migrate succeeds if admin - // check beneficiary updated - let owner = Addr::unchecked("owner"); - let beneficiary = Addr::unchecked("beneficiary"); - let init_funds = coins(30, "btc"); - - let mut app = App::new(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // create a hackatom contract with some funds - let contract_id = app.store_code(hackatom::contract()); - let contract = app - .instantiate_contract( - contract_id, - owner.clone(), - &hackatom::InstantiateMsg { - beneficiary: beneficiary.as_str().to_owned(), - }, - &coins(20, "btc"), - "Hackatom", - Some(owner.to_string()), - ) - .unwrap(); - - // check admin set properly - let info = app.contract_data(&contract).unwrap(); - assert_eq!(info.admin, Some(owner.clone())); - // check beneficiary set properly - let state: hackatom::InstantiateMsg = app - .wrap() - .query_wasm_smart(&contract, &hackatom::QueryMsg::Beneficiary {}) - .unwrap(); - assert_eq!(state.beneficiary, beneficiary); - - // migrate fails if not admin - let random = Addr::unchecked("random"); - let migrate_msg = hackatom::MigrateMsg { - new_guy: random.to_string(), - }; - app.migrate_contract(beneficiary, contract.clone(), &migrate_msg, contract_id) - .unwrap_err(); - - // migrate fails if unregistred code id - app.migrate_contract( - owner.clone(), - contract.clone(), - &migrate_msg, - contract_id + 7, - ) - .unwrap_err(); - - // migrate succeeds when the stars align - app.migrate_contract(owner, contract.clone(), &migrate_msg, contract_id) - .unwrap(); - - // check beneficiary updated - let state: hackatom::InstantiateMsg = app - .wrap() - .query_wasm_smart(&contract, &hackatom::QueryMsg::Beneficiary {}) - .unwrap(); - assert_eq!(state.beneficiary, random); - } - - #[test] - fn send_update_admin_works() { - // The plan: - // create a hackatom contract - // check admin set properly - // update admin succeeds if admin - // update admin fails if not (new) admin - // check admin set properly - let owner = Addr::unchecked("owner"); - let owner2 = Addr::unchecked("owner2"); - let beneficiary = Addr::unchecked("beneficiary"); - - let mut app = App::default(); - - // create a hackatom contract with some funds - let contract_id = app.store_code(hackatom::contract()); - let contract = app - .instantiate_contract( - contract_id, - owner.clone(), - &hackatom::InstantiateMsg { - beneficiary: beneficiary.as_str().to_owned(), - }, - &[], - "Hackatom", - Some(owner.to_string()), - ) - .unwrap(); - - // check admin set properly - let info = app.contract_data(&contract).unwrap(); - assert_eq!(info.admin, Some(owner.clone())); - - // transfer adminship to owner2 - app.execute( - owner.clone(), - CosmosMsg::Wasm(WasmMsg::UpdateAdmin { - contract_addr: contract.to_string(), - admin: owner2.to_string(), - }), - ) - .unwrap(); - - // check admin set properly - let info = app.contract_data(&contract).unwrap(); - assert_eq!(info.admin, Some(owner2.clone())); - - // update admin fails if not owner2 - app.execute( - owner.clone(), - CosmosMsg::Wasm(WasmMsg::UpdateAdmin { - contract_addr: contract.to_string(), - admin: owner.to_string(), - }), - ) - .unwrap_err(); - - // check admin still the same - let info = app.contract_data(&contract).unwrap(); - assert_eq!(info.admin, Some(owner2)); - } - - mod reply_data_overwrite { - use super::*; - - use echo::EXECUTE_REPLY_BASE_ID; - - fn make_echo_submsg( - contract: Addr, - data: impl Into>, - sub_msg: Vec, - id: u64, - ) -> SubMsg { - let data = data.into().map(|s| s.to_owned()); - SubMsg::reply_always( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract.into(), - msg: to_binary(&echo::Message { - data, - sub_msg, - ..echo::Message::default() - }) - .unwrap(), - funds: vec![], - }), - id, - ) - } - - fn make_echo_submsg_no_reply( - contract: Addr, - data: impl Into>, - sub_msg: Vec, - ) -> SubMsg { - let data = data.into().map(|s| s.to_owned()); - SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract.into(), - msg: to_binary(&echo::Message { - data, - sub_msg, - ..echo::Message::default() - }) - .unwrap(), - funds: vec![], - })) - } - - #[test] - fn no_submsg() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: Some("Data".to_owned()), - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Data".into())); - } - - #[test] - fn single_submsg() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("First".to_owned()), - sub_msg: vec![make_echo_submsg( - contract, - "Second", - vec![], - EXECUTE_REPLY_BASE_ID, - )], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Second".into())); - } - - #[test] - fn single_submsg_no_reply() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("First".to_owned()), - sub_msg: vec![make_echo_submsg_no_reply(contract, "Second", vec![])], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"First".into())); - } - - #[test] - fn single_no_submsg_data() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("First".to_owned()), - sub_msg: vec![make_echo_submsg(contract, None, vec![], 1)], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"First".into())); - } - - #[test] - fn single_no_top_level_data() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - sub_msg: vec![make_echo_submsg( - contract, - "Second", - vec![], - EXECUTE_REPLY_BASE_ID, - )], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Second".into())); - } - - #[test] - fn single_submsg_reply_returns_none() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = coins(100, "tgd"); - - let mut app = custom_app::(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up reflect contract - let reflect_id = app.store_code(reflect::contract()); - let reflect_addr = app - .instantiate_contract( - reflect_id, - owner.clone(), - &EmptyMsg {}, - &[], - "Reflect", - None, - ) - .unwrap(); - - // set up echo contract - let echo_id = app.store_code(echo::custom_contract()); - let echo_addr = app - .instantiate_contract(echo_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - // reflect will call echo - // echo will set the data - // top-level app will not display the data - let echo_msg = echo::Message:: { - data: Some("my echo".into()), - events: vec![Event::new("echo").add_attribute("called", "true")], - ..echo::Message::default() - }; - let reflect_msg = reflect::Message { - messages: vec![SubMsg::new(WasmMsg::Execute { - contract_addr: echo_addr.to_string(), - msg: to_binary(&echo_msg).unwrap(), - funds: vec![], - })], - }; - - let res = app - .execute_contract(owner, reflect_addr.clone(), &reflect_msg, &[]) - .unwrap(); - - // ensure data is empty - assert_eq!(res.data, None); - // ensure expected events - assert_eq!(res.events.len(), 3, "{:?}", res.events); - res.assert_event(&Event::new("execute").add_attribute("_contract_addr", &reflect_addr)); - res.assert_event(&Event::new("execute").add_attribute("_contract_addr", &echo_addr)); - res.assert_event(&Event::new("wasm-echo")); - } - - #[test] - fn multiple_submsg() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("Orig".to_owned()), - sub_msg: vec![ - make_echo_submsg( - contract.clone(), - None, - vec![], - EXECUTE_REPLY_BASE_ID + 1, - ), - make_echo_submsg( - contract.clone(), - "First", - vec![], - EXECUTE_REPLY_BASE_ID + 2, - ), - make_echo_submsg( - contract.clone(), - "Second", - vec![], - EXECUTE_REPLY_BASE_ID + 3, - ), - make_echo_submsg(contract, None, vec![], EXECUTE_REPLY_BASE_ID + 4), - ], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Second".into())); - } - - #[test] - fn multiple_submsg_no_reply() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("Orig".to_owned()), - sub_msg: vec![ - make_echo_submsg_no_reply(contract.clone(), None, vec![]), - make_echo_submsg_no_reply(contract.clone(), "First", vec![]), - make_echo_submsg_no_reply(contract.clone(), "Second", vec![]), - make_echo_submsg_no_reply(contract, None, vec![]), - ], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Orig".into())); - } - - #[test] - fn multiple_submsg_mixed() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - sub_msg: vec![ - make_echo_submsg( - contract.clone(), - None, - vec![], - EXECUTE_REPLY_BASE_ID + 1, - ), - make_echo_submsg_no_reply(contract.clone(), "Hidden", vec![]), - make_echo_submsg( - contract.clone(), - "Shown", - vec![], - EXECUTE_REPLY_BASE_ID + 2, - ), - make_echo_submsg( - contract.clone(), - None, - vec![], - EXECUTE_REPLY_BASE_ID + 3, - ), - make_echo_submsg_no_reply(contract, "Lost", vec![]), - ], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Shown".into())); - } - - #[test] - fn nested_submsg() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let response = app - .execute_contract( - owner, - contract.clone(), - &echo::Message { - data: Some("Orig".to_owned()), - sub_msg: vec![make_echo_submsg( - contract.clone(), - None, - vec![make_echo_submsg( - contract.clone(), - "First", - vec![make_echo_submsg( - contract.clone(), - "Second", - vec![make_echo_submsg( - contract, - None, - vec![], - EXECUTE_REPLY_BASE_ID + 4, - )], - EXECUTE_REPLY_BASE_ID + 3, - )], - EXECUTE_REPLY_BASE_ID + 2, - )], - EXECUTE_REPLY_BASE_ID + 1, - )], - ..echo::Message::default() - }, - &[], - ) - .unwrap(); - - assert_eq!(response.data, Some(b"Second".into())); - } - } - - mod response_validation { - use super::*; - - #[test] - fn empty_attribute_key() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let err = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: None, - attributes: vec![ - Attribute::new(" ", "value"), - Attribute::new("proper", "proper_val"), - ], - ..echo::Message::default() - }, - &[], - ) - .unwrap_err(); - - assert_eq!(Error::empty_attribute_key("value"), err.downcast().unwrap(),); - } - - #[test] - fn empty_attribute_value() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let err = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: None, - attributes: vec![ - Attribute::new("key", " "), - Attribute::new("proper", "proper_val"), - ], - ..echo::Message::default() - }, - &[], - ) - .unwrap_err(); - - assert_eq!(Error::empty_attribute_value("key"), err.downcast().unwrap()); - } - - #[test] - fn empty_event_attribute_key() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let err = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: None, - events: vec![Event::new("event") - .add_attribute(" ", "value") - .add_attribute("proper", "proper_val")], - ..echo::Message::default() - }, - &[], - ) - .unwrap_err(); - - assert_eq!(Error::empty_attribute_key("value"), err.downcast().unwrap()); - } - - #[test] - fn empty_event_attribute_value() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let err = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: None, - events: vec![Event::new("event") - .add_attribute("key", " ") - .add_attribute("proper", "proper_val")], - ..echo::Message::default() - }, - &[], - ) - .unwrap_err(); - - assert_eq!(Error::empty_attribute_value("key"), err.downcast().unwrap()); - } - - #[test] - fn too_short_event_type() { - let mut app = App::default(); - - let owner = Addr::unchecked("owner"); - - let contract_id = app.store_code(echo::contract()); - let contract = app - .instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - let err = app - .execute_contract( - owner, - contract, - &echo::Message:: { - data: None, - events: vec![Event::new(" e "), Event::new("event")], - ..echo::Message::default() - }, - &[], - ) - .unwrap_err(); - - assert_eq!(Error::event_type_too_short("e"), err.downcast().unwrap()); - } - } - - mod custom_messages { - use super::*; - use crate::custom_handler::CachingCustomHandler; - - #[test] - fn triggering_custom_msg() { - let api = MockApi::default(); - let sender = api.addr_validate("sender").unwrap(); - let owner = api.addr_validate("owner").unwrap(); - - let custom_handler = CachingCustomHandler::::new(); - let custom_handler_state = custom_handler.state(); - - let mut app = AppBuilder::new_custom() - .with_api(api) - .with_custom(custom_handler) - .build(no_init); - - let contract_id = app.store_code(echo::custom_contract()); - let contract = app - .instantiate_contract(contract_id, owner, &EmptyMsg {}, &[], "Echo", None) - .unwrap(); - - app.execute_contract( - sender, - contract, - &echo::Message { - sub_msg: vec![SubMsg::new(CosmosMsg::Custom(CustomMsg::SetAge { - age: 20, - }))], - ..Default::default() - }, - &[], - ) - .unwrap(); - - assert_eq!( - custom_handler_state.execs().to_owned(), - vec![CustomMsg::SetAge { age: 20 }] - ); - - assert!(custom_handler_state.queries().is_empty()); - } - } - - mod protobuf_wrapped_data { - use super::*; - use crate::test_helpers::contracts::echo::EXECUTE_REPLY_BASE_ID; - use cw_utils::parse_instantiate_response_data; - - #[test] - fn instantiate_wrapped_properly() { - // set personal balance - let owner = Addr::unchecked("owner"); - let init_funds = vec![coin(20, "btc")]; - - let mut app = custom_app::(|router, _, storage| { - router - .bank - .init_balance(storage, &owner, init_funds) - .unwrap(); - }); - - // set up reflect contract - let code_id = app.store_code(reflect::contract()); - let init_msg = to_binary(&EmptyMsg {}).unwrap(); - let msg = WasmMsg::Instantiate { - admin: None, - code_id, - msg: init_msg, - funds: vec![], - label: "label".into(), - }; - let res = app.execute(owner, msg.into()).unwrap(); - - // assert we have a proper instantiate result - let parsed = parse_instantiate_response_data(res.data.unwrap().as_slice()).unwrap(); - assert!(parsed.data.is_none()); - // check the address is right - - let count: payout::CountResponse = app - .wrap() - .query_wasm_smart(&parsed.contract_address, &reflect::QueryMsg::Count {}) - .unwrap(); - assert_eq!(count.count, 0); - } - - #[test] - fn instantiate_with_data_works() { - let owner = Addr::unchecked("owner"); - let mut app = BasicApp::new(|_, _, _| {}); - - // set up echo contract - let code_id = app.store_code(echo::contract()); - let msg = echo::InitMessage:: { - data: Some("food".into()), - sub_msg: None, - }; - let init_msg = to_binary(&msg).unwrap(); - let msg = WasmMsg::Instantiate { - admin: None, - code_id, - msg: init_msg, - funds: vec![], - label: "label".into(), - }; - let res = app.execute(owner, msg.into()).unwrap(); - - // assert we have a proper instantiate result - let parsed = parse_instantiate_response_data(res.data.unwrap().as_slice()).unwrap(); - assert!(parsed.data.is_some()); - assert_eq!(parsed.data.unwrap(), Binary::from(b"food")); - assert!(!parsed.contract_address.is_empty()); - } - - #[test] - fn instantiate_with_reply_works() { - let owner = Addr::unchecked("owner"); - let mut app = BasicApp::new(|_, _, _| {}); - - // set up echo contract - let code_id = app.store_code(echo::contract()); - let msg = echo::InitMessage:: { - data: Some("food".into()), - ..Default::default() - }; - let addr1 = app - .instantiate_contract(code_id, owner.clone(), &msg, &[], "first", None) - .unwrap(); - - // another echo contract - let msg = echo::Message:: { - data: Some("Passed to contract instantiation, returned as reply, and then returned as response".into()), - ..Default::default() - }; - let sub_msg = SubMsg::reply_on_success( - WasmMsg::Execute { - contract_addr: addr1.to_string(), - msg: to_binary(&msg).unwrap(), - funds: vec![], - }, - EXECUTE_REPLY_BASE_ID, - ); - let init_msg = echo::InitMessage:: { - data: Some("Overwrite me".into()), - sub_msg: Some(vec![sub_msg]), - }; - let init_msg = to_binary(&init_msg).unwrap(); - let msg = WasmMsg::Instantiate { - admin: None, - code_id, - msg: init_msg, - funds: vec![], - label: "label".into(), - }; - let res = app.execute(owner, msg.into()).unwrap(); - - // assert we have a proper instantiate result - let parsed = parse_instantiate_response_data(res.data.unwrap().as_slice()).unwrap(); - assert!(parsed.data.is_some()); - // Result is from the reply, not the original one - assert_eq!(parsed.data.unwrap(), Binary::from(b"Passed to contract instantiation, returned as reply, and then returned as response")); - assert!(!parsed.contract_address.is_empty()); - assert_ne!(parsed.contract_address, addr1.to_string()); - } - - #[test] - fn execute_wrapped_properly() { - let owner = Addr::unchecked("owner"); - let mut app = BasicApp::new(|_, _, _| {}); - - // set up reflect contract - let code_id = app.store_code(echo::contract()); - let echo_addr = app - .instantiate_contract(code_id, owner.clone(), &EmptyMsg {}, &[], "label", None) - .unwrap(); - - // ensure the execute has the same wrapper as it should - let msg = echo::Message:: { - data: Some("hello".into()), - ..echo::Message::default() - }; - // execute_contract now decodes a protobuf wrapper, so we get the top-level response - let exec_res = app.execute_contract(owner, echo_addr, &msg, &[]).unwrap(); - assert_eq!(exec_res.data, Some(Binary::from(b"hello"))); - } - } - - mod errors { - use super::*; - - #[test] - fn simple_instantiation() { - let owner = Addr::unchecked("owner"); - let mut app = App::default(); - - // set up contract - let code_id = app.store_code(error::contract(false)); - let msg = EmptyMsg {}; - let err = app - .instantiate_contract(code_id, owner, &msg, &[], "error", None) - .unwrap_err(); - - // we should be able to retrieve the original error by downcasting - let source: &StdError = err.downcast_ref().unwrap(); - if let StdError::GenericErr { msg } = source { - assert_eq!(msg, "Init failed"); - } else { - panic!("wrong StdError variant"); - } - - // We're expecting exactly 2 nested error types - // (the original error, WasmMsg context) - assert_eq!(err.chain().count(), 2); - } - - #[test] - fn simple_call() { - let owner = Addr::unchecked("owner"); - let mut app = App::default(); - - // set up contract - let code_id = app.store_code(error::contract(true)); - let msg = EmptyMsg {}; - let contract_addr = app - .instantiate_contract(code_id, owner, &msg, &[], "error", None) - .unwrap(); - - // execute should error - let err = app - .execute_contract(Addr::unchecked("random"), contract_addr, &msg, &[]) - .unwrap_err(); - - // we should be able to retrieve the original error by downcasting - let source: &StdError = err.downcast_ref().unwrap(); - if let StdError::GenericErr { msg } = source { - assert_eq!(msg, "Handle failed"); - } else { - panic!("wrong StdError variant"); - } - - // We're expecting exactly 2 nested error types - // (the original error, WasmMsg context) - assert_eq!(err.chain().count(), 2); - } - - #[test] - fn nested_call() { - let owner = Addr::unchecked("owner"); - let mut app = App::default(); - - let error_code_id = app.store_code(error::contract(true)); - let caller_code_id = app.store_code(caller::contract()); - - // set up contracts - let msg = EmptyMsg {}; - let caller_addr = app - .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) - .unwrap(); - let error_addr = app - .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) - .unwrap(); - - // execute should error - let msg = WasmMsg::Execute { - contract_addr: error_addr.into(), - msg: to_binary(&EmptyMsg {}).unwrap(), - funds: vec![], - }; - let err = app - .execute_contract(Addr::unchecked("random"), caller_addr, &msg, &[]) - .unwrap_err(); - - // we can downcast to get the original error - let source: &StdError = err.downcast_ref().unwrap(); - if let StdError::GenericErr { msg } = source { - assert_eq!(msg, "Handle failed"); - } else { - panic!("wrong StdError variant"); - } - - // We're expecting exactly 3 nested error types - // (the original error, 2 WasmMsg contexts) - assert_eq!(err.chain().count(), 3); - } - - #[test] - fn double_nested_call() { - let owner = Addr::unchecked("owner"); - let mut app = App::default(); - - let error_code_id = app.store_code(error::contract(true)); - let caller_code_id = app.store_code(caller::contract()); - - // set up contracts - let msg = EmptyMsg {}; - let caller_addr1 = app - .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) - .unwrap(); - let caller_addr2 = app - .instantiate_contract(caller_code_id, owner.clone(), &msg, &[], "caller", None) - .unwrap(); - let error_addr = app - .instantiate_contract(error_code_id, owner, &msg, &[], "error", None) - .unwrap(); - - // caller1 calls caller2, caller2 calls error - let msg = WasmMsg::Execute { - contract_addr: caller_addr2.into(), - msg: to_binary(&WasmMsg::Execute { - contract_addr: error_addr.into(), - msg: to_binary(&EmptyMsg {}).unwrap(), - funds: vec![], - }) - .unwrap(), - funds: vec![], - }; - let err = app - .execute_contract(Addr::unchecked("random"), caller_addr1, &msg, &[]) - .unwrap_err(); - - // uncomment to have the test fail and see how the error stringifies - // panic!("{:?}", err); - - // we can downcast to get the original error - let source: &StdError = err.downcast_ref().unwrap(); - if let StdError::GenericErr { msg } = source { - assert_eq!(msg, "Handle failed"); - } else { - panic!("wrong StdError variant"); - } - - // We're expecting exactly 4 nested error types - // (the original error, 3 WasmMsg contexts) - assert_eq!(err.chain().count(), 4); - } - } -} diff --git a/packages/multi-test/src/bank.rs b/packages/multi-test/src/bank.rs deleted file mode 100644 index 15cc66172..000000000 --- a/packages/multi-test/src/bank.rs +++ /dev/null @@ -1,473 +0,0 @@ -use anyhow::{bail, Result as AnyResult}; -use itertools::Itertools; -use schemars::JsonSchema; - -use cosmwasm_std::{ - coin, to_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankMsg, BankQuery, Binary, - BlockInfo, Coin, Event, Querier, Storage, -}; -use cw_storage_plus::Map; -use cw_utils::NativeBalance; - -use crate::app::CosmosRouter; -use crate::executor::AppResponse; -use crate::module::Module; -use crate::prefixed_storage::{prefixed, prefixed_read}; - -const BALANCES: Map<&Addr, NativeBalance> = Map::new("balances"); - -pub const NAMESPACE_BANK: &[u8] = b"bank"; - -// WIP -#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] -pub enum BankSudo { - Mint { - to_address: String, - amount: Vec, - }, -} - -pub trait Bank: Module {} - -#[derive(Default)] -pub struct BankKeeper {} - -impl BankKeeper { - pub fn new() -> Self { - BankKeeper {} - } - - // this is an "admin" function to let us adjust bank accounts in genesis - pub fn init_balance( - &self, - storage: &mut dyn Storage, - account: &Addr, - amount: Vec, - ) -> AnyResult<()> { - let mut bank_storage = prefixed(storage, NAMESPACE_BANK); - self.set_balance(&mut bank_storage, account, amount) - } - - fn set_balance( - &self, - bank_storage: &mut dyn Storage, - account: &Addr, - amount: Vec, - ) -> AnyResult<()> { - let mut balance = NativeBalance(amount); - balance.normalize(); - BALANCES - .save(bank_storage, account, &balance) - .map_err(Into::into) - } - - // this is an "admin" function to let us adjust bank accounts - fn get_balance(&self, bank_storage: &dyn Storage, account: &Addr) -> AnyResult> { - let val = BALANCES.may_load(bank_storage, account)?; - Ok(val.unwrap_or_default().into_vec()) - } - - fn send( - &self, - bank_storage: &mut dyn Storage, - from_address: Addr, - to_address: Addr, - amount: Vec, - ) -> AnyResult<()> { - self.burn(bank_storage, from_address, amount.clone())?; - self.mint(bank_storage, to_address, amount) - } - - fn mint( - &self, - bank_storage: &mut dyn Storage, - to_address: Addr, - amount: Vec, - ) -> AnyResult<()> { - let amount = self.normalize_amount(amount)?; - let b = self.get_balance(bank_storage, &to_address)?; - let b = NativeBalance(b) + NativeBalance(amount); - self.set_balance(bank_storage, &to_address, b.into_vec()) - } - - fn burn( - &self, - bank_storage: &mut dyn Storage, - from_address: Addr, - amount: Vec, - ) -> AnyResult<()> { - let amount = self.normalize_amount(amount)?; - let a = self.get_balance(bank_storage, &from_address)?; - let a = (NativeBalance(a) - amount)?; - self.set_balance(bank_storage, &from_address, a.into_vec()) - } - - /// Filters out all 0 value coins and returns an error if the resulting Vec is empty - fn normalize_amount(&self, amount: Vec) -> AnyResult> { - let res: Vec<_> = amount.into_iter().filter(|x| !x.amount.is_zero()).collect(); - if res.is_empty() { - bail!("Cannot transfer empty coins amount") - } else { - Ok(res) - } - } -} - -fn coins_to_string(coins: &[Coin]) -> String { - coins - .iter() - .map(|c| format!("{}{}", c.amount, c.denom)) - .join(",") -} - -impl Bank for BankKeeper {} - -impl Module for BankKeeper { - type ExecT = BankMsg; - type QueryT = BankQuery; - type SudoT = BankSudo; - - fn execute( - &self, - _api: &dyn Api, - storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - sender: Addr, - msg: BankMsg, - ) -> AnyResult { - let mut bank_storage = prefixed(storage, NAMESPACE_BANK); - match msg { - BankMsg::Send { to_address, amount } => { - // see https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/bank/keeper/send.go#L142-L147 - let events = vec![Event::new("transfer") - .add_attribute("recipient", &to_address) - .add_attribute("sender", &sender) - .add_attribute("amount", coins_to_string(&amount))]; - self.send( - &mut bank_storage, - sender, - Addr::unchecked(to_address), - amount, - )?; - Ok(AppResponse { events, data: None }) - } - BankMsg::Burn { amount } => { - // burn doesn't seem to emit any events - self.burn(&mut bank_storage, sender, amount)?; - Ok(AppResponse::default()) - } - m => bail!("Unsupported bank message: {:?}", m), - } - } - - fn sudo( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - msg: BankSudo, - ) -> AnyResult { - let mut bank_storage = prefixed(storage, NAMESPACE_BANK); - match msg { - BankSudo::Mint { to_address, amount } => { - let to_address = api.addr_validate(&to_address)?; - self.mint(&mut bank_storage, to_address, amount)?; - Ok(AppResponse::default()) - } - } - } - - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - _querier: &dyn Querier, - _block: &BlockInfo, - request: BankQuery, - ) -> AnyResult { - let bank_storage = prefixed_read(storage, NAMESPACE_BANK); - match request { - BankQuery::AllBalances { address } => { - let address = api.addr_validate(&address)?; - let amount = self.get_balance(&bank_storage, &address)?; - let res = AllBalanceResponse { amount }; - Ok(to_binary(&res)?) - } - BankQuery::Balance { address, denom } => { - let address = api.addr_validate(&address)?; - let all_amounts = self.get_balance(&bank_storage, &address)?; - let amount = all_amounts - .into_iter() - .find(|c| c.denom == denom) - .unwrap_or_else(|| coin(0, denom)); - let res = BalanceResponse { amount }; - Ok(to_binary(&res)?) - } - q => bail!("Unsupported bank query: {:?}", q), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - use crate::app::MockRouter; - use cosmwasm_std::testing::{mock_env, MockApi, MockQuerier, MockStorage}; - use cosmwasm_std::{coins, from_slice, Empty, StdError}; - - fn query_balance( - bank: &BankKeeper, - api: &dyn Api, - store: &dyn Storage, - rcpt: &Addr, - ) -> Vec { - let req = BankQuery::AllBalances { - address: rcpt.clone().into(), - }; - let block = mock_env().block; - let querier: MockQuerier = MockQuerier::new(&[]); - - let raw = bank.query(api, store, &querier, &block, req).unwrap(); - let res: AllBalanceResponse = from_slice(&raw).unwrap(); - res.amount - } - - #[test] - fn get_set_balance() { - let api = MockApi::default(); - let mut store = MockStorage::new(); - let block = mock_env().block; - let querier: MockQuerier = MockQuerier::new(&[]); - - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("receiver"); - let init_funds = vec![coin(100, "eth"), coin(20, "btc")]; - let norm = vec![coin(20, "btc"), coin(100, "eth")]; - - // set money - let bank = BankKeeper::new(); - bank.init_balance(&mut store, &owner, init_funds).unwrap(); - let bank_storage = prefixed_read(&store, NAMESPACE_BANK); - - // get balance work - let rich = bank.get_balance(&bank_storage, &owner).unwrap(); - assert_eq!(rich, norm); - let poor = bank.get_balance(&bank_storage, &rcpt).unwrap(); - assert_eq!(poor, vec![]); - - // proper queries work - let req = BankQuery::AllBalances { - address: owner.clone().into(), - }; - let raw = bank.query(&api, &store, &querier, &block, req).unwrap(); - let res: AllBalanceResponse = from_slice(&raw).unwrap(); - assert_eq!(res.amount, norm); - - let req = BankQuery::AllBalances { - address: rcpt.clone().into(), - }; - let raw = bank.query(&api, &store, &querier, &block, req).unwrap(); - let res: AllBalanceResponse = from_slice(&raw).unwrap(); - assert_eq!(res.amount, vec![]); - - let req = BankQuery::Balance { - address: owner.clone().into(), - denom: "eth".into(), - }; - let raw = bank.query(&api, &store, &querier, &block, req).unwrap(); - let res: BalanceResponse = from_slice(&raw).unwrap(); - assert_eq!(res.amount, coin(100, "eth")); - - let req = BankQuery::Balance { - address: owner.into(), - denom: "foobar".into(), - }; - let raw = bank.query(&api, &store, &querier, &block, req).unwrap(); - let res: BalanceResponse = from_slice(&raw).unwrap(); - assert_eq!(res.amount, coin(0, "foobar")); - - let req = BankQuery::Balance { - address: rcpt.into(), - denom: "eth".into(), - }; - let raw = bank.query(&api, &store, &querier, &block, req).unwrap(); - let res: BalanceResponse = from_slice(&raw).unwrap(); - assert_eq!(res.amount, coin(0, "eth")); - } - - #[test] - fn send_coins() { - let api = MockApi::default(); - let mut store = MockStorage::new(); - let block = mock_env().block; - let router = MockRouter::default(); - - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("receiver"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - let rcpt_funds = vec![coin(5, "btc")]; - - // set money - let bank = BankKeeper::new(); - bank.init_balance(&mut store, &owner, init_funds).unwrap(); - bank.init_balance(&mut store, &rcpt, rcpt_funds).unwrap(); - - // send both tokens - let to_send = vec![coin(30, "eth"), coin(5, "btc")]; - let msg = BankMsg::Send { - to_address: rcpt.clone().into(), - amount: to_send, - }; - bank.execute( - &api, - &mut store, - &router, - &block, - owner.clone(), - msg.clone(), - ) - .unwrap(); - let rich = query_balance(&bank, &api, &store, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - let poor = query_balance(&bank, &api, &store, &rcpt); - assert_eq!(vec![coin(10, "btc"), coin(30, "eth")], poor); - - // can send from any account with funds - bank.execute(&api, &mut store, &router, &block, rcpt.clone(), msg) - .unwrap(); - - // cannot send too much - let msg = BankMsg::Send { - to_address: rcpt.into(), - amount: coins(20, "btc"), - }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap_err(); - - let rich = query_balance(&bank, &api, &store, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - } - - #[test] - fn burn_coins() { - let api = MockApi::default(); - let mut store = MockStorage::new(); - let block = mock_env().block; - let router = MockRouter::default(); - - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("recipient"); - let init_funds = vec![coin(20, "btc"), coin(100, "eth")]; - - // set money - let bank = BankKeeper::new(); - bank.init_balance(&mut store, &owner, init_funds).unwrap(); - - // burn both tokens - let to_burn = vec![coin(30, "eth"), coin(5, "btc")]; - let msg = BankMsg::Burn { amount: to_burn }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap(); - let rich = query_balance(&bank, &api, &store, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - - // cannot burn too much - let msg = BankMsg::Burn { - amount: coins(20, "btc"), - }; - let err = bank - .execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap_err(); - assert!(matches!(err.downcast().unwrap(), StdError::Overflow { .. })); - - let rich = query_balance(&bank, &api, &store, &owner); - assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich); - - // cannot burn from empty account - let msg = BankMsg::Burn { - amount: coins(1, "btc"), - }; - let err = bank - .execute(&api, &mut store, &router, &block, rcpt, msg) - .unwrap_err(); - assert!(matches!(err.downcast().unwrap(), StdError::Overflow { .. })); - } - - #[test] - fn fail_on_zero_values() { - let api = MockApi::default(); - let mut store = MockStorage::new(); - let block = mock_env().block; - let router = MockRouter::default(); - - let owner = Addr::unchecked("owner"); - let rcpt = Addr::unchecked("recipient"); - let init_funds = vec![coin(5000, "atom"), coin(100, "eth")]; - - // set money - let bank = BankKeeper::new(); - bank.init_balance(&mut store, &owner, init_funds).unwrap(); - - // can send normal amounts - let msg = BankMsg::Send { - to_address: rcpt.to_string(), - amount: coins(100, "atom"), - }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap(); - - // fails send on no coins - let msg = BankMsg::Send { - to_address: rcpt.to_string(), - amount: vec![], - }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap_err(); - - // fails send on 0 coins - let msg = BankMsg::Send { - to_address: rcpt.to_string(), - amount: coins(0, "atom"), - }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap_err(); - - // fails burn on no coins - let msg = BankMsg::Burn { amount: vec![] }; - bank.execute(&api, &mut store, &router, &block, owner.clone(), msg) - .unwrap_err(); - - // fails burn on 0 coins - let msg = BankMsg::Burn { - amount: coins(0, "atom"), - }; - bank.execute(&api, &mut store, &router, &block, owner, msg) - .unwrap_err(); - - // can mint via sudo - let msg = BankSudo::Mint { - to_address: rcpt.to_string(), - amount: coins(4321, "atom"), - }; - bank.sudo(&api, &mut store, &router, &block, msg).unwrap(); - - // mint fails with 0 tokens - let msg = BankSudo::Mint { - to_address: rcpt.to_string(), - amount: coins(0, "atom"), - }; - bank.sudo(&api, &mut store, &router, &block, msg) - .unwrap_err(); - - // mint fails with no tokens - let msg = BankSudo::Mint { - to_address: rcpt.to_string(), - amount: vec![], - }; - bank.sudo(&api, &mut store, &router, &block, msg) - .unwrap_err(); - } -} diff --git a/packages/multi-test/src/contracts.rs b/packages/multi-test/src/contracts.rs deleted file mode 100644 index b38cdc114..000000000 --- a/packages/multi-test/src/contracts.rs +++ /dev/null @@ -1,437 +0,0 @@ -use schemars::JsonSchema; -use serde::de::DeserializeOwned; -use std::error::Error; -use std::fmt::{self, Debug, Display}; -use std::ops::Deref; - -use cosmwasm_std::{ - from_slice, Binary, CosmosMsg, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, - QuerierWrapper, Reply, Response, SubMsg, -}; - -use anyhow::{anyhow, bail, Result as AnyResult}; - -/// Interface to call into a Contract -pub trait Contract -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, - Q: CustomQuery, -{ - fn execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult>; - - fn instantiate( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult>; - - fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult; - - fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; - - fn reply(&self, deps: DepsMut, env: Env, msg: Reply) -> AnyResult>; - - fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult>; -} - -type ContractFn = - fn(deps: DepsMut, env: Env, info: MessageInfo, msg: T) -> Result, E>; -type PermissionedFn = fn(deps: DepsMut, env: Env, msg: T) -> Result, E>; -type ReplyFn = fn(deps: DepsMut, env: Env, msg: Reply) -> Result, E>; -type QueryFn = fn(deps: Deps, env: Env, msg: T) -> Result; - -type ContractClosure = - Box, Env, MessageInfo, T) -> Result, E>>; -type PermissionedClosure = Box, Env, T) -> Result, E>>; -type ReplyClosure = Box, Env, Reply) -> Result, E>>; -type QueryClosure = Box, Env, T) -> Result>; - -/// Wraps the exported functions from a contract and provides the normalized format -/// Place T4 and E4 at the end, as we just want default placeholders for most contracts that don't have sudo -pub struct ContractWrapper< - T1, - T2, - T3, - E1, - E2, - E3, - C = Empty, - Q = Empty, - T4 = Empty, - E4 = anyhow::Error, - E5 = anyhow::Error, - T6 = Empty, - E6 = anyhow::Error, -> where - T1: DeserializeOwned + Debug, - T2: DeserializeOwned, - T3: DeserializeOwned, - T4: DeserializeOwned, - T6: DeserializeOwned, - E1: Display + Debug + Send + Sync + 'static, - E2: Display + Debug + Send + Sync + 'static, - E3: Display + Debug + Send + Sync + 'static, - E4: Display + Debug + Send + Sync + 'static, - E5: Display + Debug + Send + Sync + 'static, - E6: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema, - Q: CustomQuery + DeserializeOwned + 'static, -{ - execute_fn: ContractClosure, - instantiate_fn: ContractClosure, - query_fn: QueryClosure, - sudo_fn: Option>, - reply_fn: Option>, - migrate_fn: Option>, -} - -impl ContractWrapper -where - T1: DeserializeOwned + Debug + 'static, - T2: DeserializeOwned + 'static, - T3: DeserializeOwned + 'static, - E1: Display + Debug + Send + Sync + 'static, - E2: Display + Debug + Send + Sync + 'static, - E3: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, - Q: CustomQuery + DeserializeOwned + 'static, -{ - pub fn new( - execute_fn: ContractFn, - instantiate_fn: ContractFn, - query_fn: QueryFn, - ) -> Self { - Self { - execute_fn: Box::new(execute_fn), - instantiate_fn: Box::new(instantiate_fn), - query_fn: Box::new(query_fn), - sudo_fn: None, - reply_fn: None, - migrate_fn: None, - } - } - - /// this will take a contract that returns Response and will "upgrade" it - /// to Response if needed to be compatible with a chain-specific extension - pub fn new_with_empty( - execute_fn: ContractFn, - instantiate_fn: ContractFn, - query_fn: QueryFn, - ) -> Self { - Self { - execute_fn: customize_fn(execute_fn), - instantiate_fn: customize_fn(instantiate_fn), - query_fn: customize_query(query_fn), - sudo_fn: None, - reply_fn: None, - migrate_fn: None, - } - } -} - -impl - ContractWrapper -where - T1: DeserializeOwned + Debug + 'static, - T2: DeserializeOwned + 'static, - T3: DeserializeOwned + 'static, - T4: DeserializeOwned + 'static, - T6: DeserializeOwned + 'static, - E1: Display + Debug + Send + Sync + 'static, - E2: Display + Debug + Send + Sync + 'static, - E3: Display + Debug + Send + Sync + 'static, - E4: Display + Debug + Send + Sync + 'static, - E5: Display + Debug + Send + Sync + 'static, - E6: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, - Q: CustomQuery + DeserializeOwned + 'static, -{ - pub fn with_sudo( - self, - sudo_fn: PermissionedFn, - ) -> ContractWrapper - where - T4A: DeserializeOwned + 'static, - E4A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: Some(Box::new(sudo_fn)), - reply_fn: self.reply_fn, - migrate_fn: self.migrate_fn, - } - } - - pub fn with_sudo_empty( - self, - sudo_fn: PermissionedFn, - ) -> ContractWrapper - where - T4A: DeserializeOwned + 'static, - E4A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: Some(customize_permissioned_fn(sudo_fn)), - reply_fn: self.reply_fn, - migrate_fn: self.migrate_fn, - } - } - - pub fn with_reply( - self, - reply_fn: ReplyFn, - ) -> ContractWrapper - where - E5A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: self.sudo_fn, - reply_fn: Some(Box::new(reply_fn)), - migrate_fn: self.migrate_fn, - } - } - - /// A correlate of new_with_empty - pub fn with_reply_empty( - self, - reply_fn: ReplyFn, - ) -> ContractWrapper - where - E5A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: self.sudo_fn, - reply_fn: Some(customize_permissioned_fn(reply_fn)), - migrate_fn: self.migrate_fn, - } - } - - pub fn with_migrate( - self, - migrate_fn: PermissionedFn, - ) -> ContractWrapper - where - T6A: DeserializeOwned + 'static, - E6A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: self.sudo_fn, - reply_fn: self.reply_fn, - migrate_fn: Some(Box::new(migrate_fn)), - } - } - - pub fn with_migrate_empty( - self, - migrate_fn: PermissionedFn, - ) -> ContractWrapper - where - T6A: DeserializeOwned + 'static, - E6A: Display + Debug + Send + Sync + 'static, - { - ContractWrapper { - execute_fn: self.execute_fn, - instantiate_fn: self.instantiate_fn, - query_fn: self.query_fn, - sudo_fn: self.sudo_fn, - reply_fn: self.reply_fn, - migrate_fn: Some(customize_permissioned_fn(migrate_fn)), - } - } -} - -fn customize_fn(raw_fn: ContractFn) -> ContractClosure -where - T: DeserializeOwned + 'static, - E: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, - Q: CustomQuery + DeserializeOwned + 'static, -{ - let customized = move |mut deps: DepsMut, - env: Env, - info: MessageInfo, - msg: T| - -> Result, E> { - let deps = decustomize_deps_mut(&mut deps); - raw_fn(deps, env, info, msg).map(customize_response::) - }; - Box::new(customized) -} - -fn customize_query(raw_fn: QueryFn) -> QueryClosure -where - T: DeserializeOwned + 'static, - E: Display + Debug + Send + Sync + 'static, - Q: CustomQuery + DeserializeOwned + 'static, -{ - let customized = move |deps: Deps, env: Env, msg: T| -> Result { - let deps = decustomize_deps(&deps); - raw_fn(deps, env, msg) - }; - Box::new(customized) -} - -fn decustomize_deps_mut<'a, Q>(deps: &'a mut DepsMut) -> DepsMut<'a, Empty> -where - Q: CustomQuery + DeserializeOwned + 'static, -{ - DepsMut { - storage: deps.storage, - api: deps.api, - querier: QuerierWrapper::new(deps.querier.deref()), - } -} - -fn decustomize_deps<'a, Q>(deps: &'a Deps<'a, Q>) -> Deps<'a, Empty> -where - Q: CustomQuery + DeserializeOwned + 'static, -{ - Deps { - storage: deps.storage, - api: deps.api, - querier: QuerierWrapper::new(deps.querier.deref()), - } -} - -fn customize_permissioned_fn( - raw_fn: PermissionedFn, -) -> PermissionedClosure -where - T: DeserializeOwned + 'static, - E: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, - Q: CustomQuery + DeserializeOwned + 'static, -{ - let customized = move |deps: DepsMut, env: Env, msg: T| -> Result, E> { - raw_fn(deps, env, msg).map(customize_response::) - }; - Box::new(customized) -} - -fn customize_response(resp: Response) -> Response -where - C: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - let mut customized_resp = Response::::new() - .add_submessages(resp.messages.into_iter().map(customize_msg::)) - .add_events(resp.events) - .add_attributes(resp.attributes); - customized_resp.data = resp.data; - customized_resp -} - -fn customize_msg(msg: SubMsg) -> SubMsg -where - C: Clone + fmt::Debug + PartialEq + JsonSchema, -{ - SubMsg { - msg: match msg.msg { - CosmosMsg::Wasm(wasm) => CosmosMsg::Wasm(wasm), - CosmosMsg::Bank(bank) => CosmosMsg::Bank(bank), - CosmosMsg::Staking(staking) => CosmosMsg::Staking(staking), - CosmosMsg::Distribution(distribution) => CosmosMsg::Distribution(distribution), - CosmosMsg::Custom(_) => unreachable!(), - #[cfg(feature = "stargate")] - CosmosMsg::Ibc(ibc) => CosmosMsg::Ibc(ibc), - #[cfg(feature = "stargate")] - CosmosMsg::Stargate { type_url, value } => CosmosMsg::Stargate { type_url, value }, - _ => panic!("unknown message variant {:?}", msg), - }, - id: msg.id, - gas_limit: msg.gas_limit, - reply_on: msg.reply_on, - } -} - -impl Contract - for ContractWrapper -where - T1: DeserializeOwned + Debug + Clone, - T2: DeserializeOwned + Debug + Clone, - T3: DeserializeOwned + Debug + Clone, - T4: DeserializeOwned, - T6: DeserializeOwned, - E1: Display + Debug + Send + Sync + Error + 'static, - E2: Display + Debug + Send + Sync + Error + 'static, - E3: Display + Debug + Send + Sync + Error + 'static, - E4: Display + Debug + Send + Sync + 'static, - E5: Display + Debug + Send + Sync + 'static, - E6: Display + Debug + Send + Sync + 'static, - C: Clone + fmt::Debug + PartialEq + JsonSchema, - Q: CustomQuery + DeserializeOwned, -{ - fn execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - let msg: T1 = from_slice(&msg)?; - (self.execute_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) - } - - fn instantiate( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - let msg: T2 = from_slice(&msg)?; - (self.instantiate_fn)(deps, env, info, msg).map_err(|err| anyhow!(err)) - } - - fn query(&self, deps: Deps, env: Env, msg: Vec) -> AnyResult { - let msg: T3 = from_slice(&msg)?; - (self.query_fn)(deps, env, msg).map_err(|err| anyhow!(err)) - } - - // this returns an error if the contract doesn't implement sudo - fn sudo(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { - let msg = from_slice(&msg)?; - match &self.sudo_fn { - Some(sudo) => sudo(deps, env, msg).map_err(|err| anyhow!(err)), - None => bail!("sudo not implemented for contract"), - } - } - - // this returns an error if the contract doesn't implement reply - fn reply(&self, deps: DepsMut, env: Env, reply_data: Reply) -> AnyResult> { - match &self.reply_fn { - Some(reply) => reply(deps, env, reply_data).map_err(|err| anyhow!(err)), - None => bail!("reply not implemented for contract"), - } - } - - // this returns an error if the contract doesn't implement migrate - fn migrate(&self, deps: DepsMut, env: Env, msg: Vec) -> AnyResult> { - let msg = from_slice(&msg)?; - match &self.migrate_fn { - Some(migrate) => migrate(deps, env, msg).map_err(|err| anyhow!(err)), - None => bail!("migrate not implemented for contract"), - } - } -} diff --git a/packages/multi-test/src/custom_handler.rs b/packages/multi-test/src/custom_handler.rs deleted file mode 100644 index 298f58cce..000000000 --- a/packages/multi-test/src/custom_handler.rs +++ /dev/null @@ -1,93 +0,0 @@ -use anyhow::{bail, Result as AnyResult}; -use derivative::Derivative; -use std::cell::{Ref, RefCell}; -use std::ops::Deref; -use std::rc::Rc; - -use cosmwasm_std::{Addr, Api, Binary, BlockInfo, Empty, Querier, Storage}; - -use crate::app::CosmosRouter; -use crate::{AppResponse, Module}; - -/// Internal state of `CachingCustomHandler` wrapping internal mutability so it is not exposed to -/// user. Those have to be shared internal state, as after mock is passed to app it is not -/// possible to access mock internals which are not exposed by API. -#[derive(Derivative)] -#[derivative(Default(bound = "", new = "true"), Clone(bound = ""))] -pub struct CachingCustomHandlerState { - execs: Rc>>, - queries: Rc>>, -} - -impl CachingCustomHandlerState { - pub fn execs(&self) -> impl Deref + '_ { - Ref::map(self.execs.borrow(), Vec::as_slice) - } - - pub fn queries(&self) -> impl Deref + '_ { - Ref::map(self.queries.borrow(), Vec::as_slice) - } - - pub fn reset(&self) { - self.execs.borrow_mut().clear(); - self.queries.borrow_mut().clear(); - } -} - -/// Custom handler storing all the messages it received, so they can be later verified. State is -/// thin shared state, so it can be hold after mock is passed to App to read state. -#[derive(Clone, Derivative)] -#[derivative(Default(bound = "", new = "true"))] -pub struct CachingCustomHandler { - state: CachingCustomHandlerState, -} - -impl CachingCustomHandler { - pub fn state(&self) -> CachingCustomHandlerState { - self.state.clone() - } -} - -impl Module for CachingCustomHandler { - type ExecT = Exec; - type QueryT = Query; - type SudoT = Empty; - - // TODO: how to assert - // where ExecC: Exec, QueryC: Query - fn execute( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - _sender: Addr, - msg: Self::ExecT, - ) -> AnyResult { - self.state.execs.borrow_mut().push(msg); - Ok(AppResponse::default()) - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - msg: Self::SudoT, - ) -> AnyResult { - bail!("Unexpected sudo msg {:?}", msg) - } - - fn query( - &self, - _api: &dyn Api, - _storage: &dyn Storage, - _querier: &dyn Querier, - _block: &BlockInfo, - request: Self::QueryT, - ) -> AnyResult { - self.state.queries.borrow_mut().push(request); - Ok(Binary::default()) - } -} diff --git a/packages/multi-test/src/error.rs b/packages/multi-test/src/error.rs deleted file mode 100644 index f0bd0920d..000000000 --- a/packages/multi-test/src/error.rs +++ /dev/null @@ -1,46 +0,0 @@ -use cosmwasm_std::{WasmMsg, WasmQuery}; -use thiserror::Error; - -#[derive(Debug, Error, PartialEq, Eq)] -pub enum Error { - #[error("Empty attribute key. Value: {value}")] - EmptyAttributeKey { value: String }, - - #[error("Empty attribute value. Key: {key}")] - EmptyAttributeValue { key: String }, - - #[error("Attribute key strats with reserved prefix _: {0}")] - ReservedAttributeKey(String), - - #[error("Event type too short: {0}")] - EventTypeTooShort(String), - - #[error("Unsupported wasm query: {0:?}")] - UnsupportedWasmQuery(WasmQuery), - - #[error("Unsupported wasm message: {0:?}")] - UnsupportedWasmMsg(WasmMsg), - - #[error("Unregistered code id")] - UnregisteredCodeId(usize), -} - -impl Error { - pub fn empty_attribute_key(value: impl Into) -> Self { - Self::EmptyAttributeKey { - value: value.into(), - } - } - - pub fn empty_attribute_value(key: impl Into) -> Self { - Self::EmptyAttributeValue { key: key.into() } - } - - pub fn reserved_attribute_key(key: impl Into) -> Self { - Self::ReservedAttributeKey(key.into()) - } - - pub fn event_type_too_short(ty: impl Into) -> Self { - Self::EventTypeTooShort(ty.into()) - } -} diff --git a/packages/multi-test/src/executor.rs b/packages/multi-test/src/executor.rs deleted file mode 100644 index 75be02d60..000000000 --- a/packages/multi-test/src/executor.rs +++ /dev/null @@ -1,150 +0,0 @@ -use std::fmt; - -use cosmwasm_std::{ - to_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, Event, SubMsgResponse, WasmMsg, -}; -use cw_utils::{parse_execute_response_data, parse_instantiate_response_data}; -use schemars::JsonSchema; -use serde::Serialize; - -use anyhow::Result as AnyResult; - -#[derive(Default, Clone, Debug)] -pub struct AppResponse { - pub events: Vec, - pub data: Option, -} - -impl AppResponse { - // Return all custom attributes returned by the contract in the `idx` event. - // We assert the type is wasm, and skip the contract_address attribute. - #[track_caller] - pub fn custom_attrs(&self, idx: usize) -> &[Attribute] { - assert_eq!(self.events[idx].ty.as_str(), "wasm"); - &self.events[idx].attributes[1..] - } - - /// Check if there is an Event that is a super-set of this. - /// It has the same type, and all compare.attributes are included in it as well. - /// You don't need to specify them all. - pub fn has_event(&self, expected: &Event) -> bool { - self.events.iter().any(|ev| { - expected.ty == ev.ty - && expected - .attributes - .iter() - .all(|at| ev.attributes.contains(at)) - }) - } - - /// Like has_event but panics if no match - #[track_caller] - pub fn assert_event(&self, expected: &Event) { - assert!( - self.has_event(expected), - "Expected to find an event {:?}, but received: {:?}", - expected, - self.events - ); - } -} - -/// They have the same shape, SubMsgExecutionResponse is what is returned in reply. -/// This is just to make some test cases easier. -impl From for AppResponse { - fn from(reply: SubMsgResponse) -> Self { - AppResponse { - data: reply.data, - events: reply.events, - } - } -} - -pub trait Executor -where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, -{ - /// Runs arbitrary CosmosMsg. - /// This will create a cache before the execution, so no state changes are persisted if this - /// returns an error, but all are persisted on success. - fn execute(&mut self, sender: Addr, msg: CosmosMsg) -> AnyResult; - - /// Create a contract and get the new address. - /// This is just a helper around execute() - fn instantiate_contract>( - &mut self, - code_id: u64, - sender: Addr, - init_msg: &T, - send_funds: &[Coin], - label: U, - admin: Option, - ) -> AnyResult { - // instantiate contract - let init_msg = to_binary(init_msg)?; - let msg = WasmMsg::Instantiate { - admin, - code_id, - msg: init_msg, - funds: send_funds.to_vec(), - label: label.into(), - }; - let res = self.execute(sender, msg.into())?; - let data = parse_instantiate_response_data(res.data.unwrap_or_default().as_slice())?; - Ok(Addr::unchecked(data.contract_address)) - } - - /// Execute a contract and process all returned messages. - /// This is just a helper around execute(), - /// but we parse out the data field to that what is returned by the contract (not the protobuf wrapper) - fn execute_contract( - &mut self, - sender: Addr, - contract_addr: Addr, - msg: &T, - send_funds: &[Coin], - ) -> AnyResult { - let binary_msg = to_binary(msg)?; - let wrapped_msg = WasmMsg::Execute { - contract_addr: contract_addr.into_string(), - msg: binary_msg, - funds: send_funds.to_vec(), - }; - let mut res = self.execute(sender, wrapped_msg.into())?; - res.data = res - .data - .and_then(|d| parse_execute_response_data(d.as_slice()).unwrap().data); - Ok(res) - } - - /// Migrate a contract. Sender must be registered admin. - /// This is just a helper around execute() - fn migrate_contract( - &mut self, - sender: Addr, - contract_addr: Addr, - msg: &T, - new_code_id: u64, - ) -> AnyResult { - let msg = to_binary(msg)?; - let msg = WasmMsg::Migrate { - contract_addr: contract_addr.into(), - msg, - new_code_id, - }; - self.execute(sender, msg.into()) - } - - fn send_tokens( - &mut self, - sender: Addr, - recipient: Addr, - amount: &[Coin], - ) -> AnyResult { - let msg = BankMsg::Send { - to_address: recipient.to_string(), - amount: amount.to_vec(), - }; - self.execute(sender, msg.into()) - } -} diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs deleted file mode 100644 index 7d9ae4ff9..000000000 --- a/packages/multi-test/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Multitest is a design to simulate a blockchain environment in pure Rust. -//! This allows us to run unit tests that involve contract -> contract, -//! and contract -> bank interactions. This is not intended to be a full blockchain app -//! but to simulate the Cosmos SDK x/wasm module close enough to gain confidence in -//! multi-contract deployements before testing them on a live blockchain. -//! -//! To understand the design of this module, please refer to `../DESIGN.md` - -mod app; -mod bank; -#[allow(clippy::type_complexity)] -mod contracts; -pub mod custom_handler; -pub mod error; -mod executor; -mod module; -mod prefixed_storage; -mod staking; -mod test_helpers; -mod transactions; -mod wasm; - -pub use crate::app::{ - custom_app, next_block, App, AppBuilder, BasicApp, BasicAppBuilder, CosmosRouter, Router, - SudoMsg, -}; -pub use crate::bank::{Bank, BankKeeper, BankSudo}; -pub use crate::contracts::{Contract, ContractWrapper}; -pub use crate::executor::{AppResponse, Executor}; -pub use crate::module::{FailingModule, Module}; -pub use crate::staking::{DistributionKeeper, StakeKeeper, Staking, StakingInfo, StakingSudo}; -pub use crate::wasm::{Wasm, WasmKeeper, WasmSudo}; diff --git a/packages/multi-test/src/module.rs b/packages/multi-test/src/module.rs deleted file mode 100644 index 7125a3e4d..000000000 --- a/packages/multi-test/src/module.rs +++ /dev/null @@ -1,115 +0,0 @@ -use std::marker::PhantomData; - -use anyhow::{bail, Result as AnyResult}; -use cosmwasm_std::{Addr, Api, Binary, BlockInfo, CustomQuery, Querier, Storage}; - -use crate::app::CosmosRouter; -use crate::AppResponse; -use schemars::JsonSchema; -use serde::de::DeserializeOwned; - -pub trait Module { - type ExecT; - type QueryT; - type SudoT; - - /// execute runs any ExecT message, which can be called by any external actor - /// or smart contract - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - msg: Self::ExecT, - ) -> AnyResult - where - ExecC: std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static; - - /// sudo runs privileged actions, like minting tokens, or governance proposals. - /// This allows modules to have full access to these privileged actions, - /// that cannot be triggered by smart contracts. - /// - /// There is no sender, as this must be previously authorized before the call - fn sudo( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: Self::SudoT, - ) -> AnyResult - where - ExecC: std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static; - - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - request: Self::QueryT, - ) -> AnyResult; -} - -pub struct FailingModule(PhantomData<(ExecT, QueryT, SudoT)>); - -impl FailingModule { - pub fn new() -> Self { - FailingModule(PhantomData) - } -} - -impl Default for FailingModule { - fn default() -> Self { - Self::new() - } -} - -impl Module for FailingModule -where - Exec: std::fmt::Debug, - Query: std::fmt::Debug, - Sudo: std::fmt::Debug, -{ - type ExecT = Exec; - type QueryT = Query; - type SudoT = Sudo; - - fn execute( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - sender: Addr, - msg: Self::ExecT, - ) -> AnyResult { - bail!("Unexpected exec msg {:?} from {:?}", msg, sender) - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - msg: Self::SudoT, - ) -> AnyResult { - bail!("Unexpected sudo msg {:?}", msg) - } - - fn query( - &self, - _api: &dyn Api, - _storage: &dyn Storage, - _querier: &dyn Querier, - _block: &BlockInfo, - request: Self::QueryT, - ) -> AnyResult { - bail!("Unexpected custom query {:?}", request) - } -} diff --git a/packages/multi-test/src/prefixed_storage.rs b/packages/multi-test/src/prefixed_storage.rs deleted file mode 100644 index b74e4d764..000000000 --- a/packages/multi-test/src/prefixed_storage.rs +++ /dev/null @@ -1,185 +0,0 @@ -mod length_prefixed; -mod namespace_helpers; - -use cosmwasm_std::Storage; -#[cfg(feature = "iterator")] -use cosmwasm_std::{Order, Record}; - -use length_prefixed::{to_length_prefixed, to_length_prefixed_nested}; -#[cfg(feature = "iterator")] -use namespace_helpers::range_with_prefix; -use namespace_helpers::{get_with_prefix, remove_with_prefix, set_with_prefix}; - -/// An alias of PrefixedStorage::new for less verbose usage -pub fn prefixed<'a>(storage: &'a mut dyn Storage, namespace: &[u8]) -> PrefixedStorage<'a> { - PrefixedStorage::new(storage, namespace) -} - -/// An alias of ReadonlyPrefixedStorage::new for less verbose usage -pub fn prefixed_read<'a>( - storage: &'a dyn Storage, - namespace: &[u8], -) -> ReadonlyPrefixedStorage<'a> { - ReadonlyPrefixedStorage::new(storage, namespace) -} - -pub struct PrefixedStorage<'a> { - storage: &'a mut dyn Storage, - prefix: Vec, -} - -impl<'a> PrefixedStorage<'a> { - pub fn new(storage: &'a mut dyn Storage, namespace: &[u8]) -> Self { - PrefixedStorage { - storage, - prefix: to_length_prefixed(namespace), - } - } - - // Nested namespaces as documented in - // https://github.com/webmaster128/key-namespacing#nesting - pub fn multilevel(storage: &'a mut dyn Storage, namespaces: &[&[u8]]) -> Self { - PrefixedStorage { - storage, - prefix: to_length_prefixed_nested(namespaces), - } - } -} - -impl<'a> Storage for PrefixedStorage<'a> { - fn get(&self, key: &[u8]) -> Option> { - get_with_prefix(self.storage, &self.prefix, key) - } - - fn set(&mut self, key: &[u8], value: &[u8]) { - set_with_prefix(self.storage, &self.prefix, key, value); - } - - fn remove(&mut self, key: &[u8]) { - remove_with_prefix(self.storage, &self.prefix, key); - } - - #[cfg(feature = "iterator")] - /// range allows iteration over a set of keys, either forwards or backwards - /// uses standard rust range notation, and eg db.range(b"foo"..b"bar") also works reverse - fn range<'b>( - &'b self, - start: Option<&[u8]>, - end: Option<&[u8]>, - order: Order, - ) -> Box + 'b> { - range_with_prefix(self.storage, &self.prefix, start, end, order) - } -} - -pub struct ReadonlyPrefixedStorage<'a> { - storage: &'a dyn Storage, - prefix: Vec, -} - -impl<'a> ReadonlyPrefixedStorage<'a> { - pub fn new(storage: &'a dyn Storage, namespace: &[u8]) -> Self { - ReadonlyPrefixedStorage { - storage, - prefix: to_length_prefixed(namespace), - } - } - - // Nested namespaces as documented in - // https://github.com/webmaster128/key-namespacing#nesting - pub fn multilevel(storage: &'a dyn Storage, namespaces: &[&[u8]]) -> Self { - ReadonlyPrefixedStorage { - storage, - prefix: to_length_prefixed_nested(namespaces), - } - } -} - -impl<'a> Storage for ReadonlyPrefixedStorage<'a> { - fn get(&self, key: &[u8]) -> Option> { - get_with_prefix(self.storage, &self.prefix, key) - } - - fn set(&mut self, _key: &[u8], _value: &[u8]) { - unimplemented!(); - } - - fn remove(&mut self, _key: &[u8]) { - unimplemented!(); - } - - #[cfg(feature = "iterator")] - /// range allows iteration over a set of keys, either forwards or backwards - fn range<'b>( - &'b self, - start: Option<&[u8]>, - end: Option<&[u8]>, - order: Order, - ) -> Box + 'b> { - range_with_prefix(self.storage, &self.prefix, start, end, order) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn prefixed_storage_set_and_get() { - let mut storage = MockStorage::new(); - - // set - let mut s1 = PrefixedStorage::new(&mut storage, b"foo"); - s1.set(b"bar", b"gotcha"); - assert_eq!(storage.get(b"\x00\x03foobar").unwrap(), b"gotcha".to_vec()); - - // get - let s2 = PrefixedStorage::new(&mut storage, b"foo"); - assert_eq!(s2.get(b"bar"), Some(b"gotcha".to_vec())); - assert_eq!(s2.get(b"elsewhere"), None); - } - - #[test] - fn prefixed_storage_multilevel_set_and_get() { - let mut storage = MockStorage::new(); - - // set - let mut bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]); - bar.set(b"baz", b"winner"); - assert_eq!( - storage.get(b"\x00\x03foo\x00\x03barbaz").unwrap(), - b"winner".to_vec() - ); - - // get - let bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]); - assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec())); - assert_eq!(bar.get(b"elsewhere"), None); - } - - #[test] - fn readonly_prefixed_storage_get() { - let mut storage = MockStorage::new(); - storage.set(b"\x00\x03foobar", b"gotcha"); - - // try readonly correctly - let s1 = ReadonlyPrefixedStorage::new(&storage, b"foo"); - assert_eq!(s1.get(b"bar"), Some(b"gotcha".to_vec())); - assert_eq!(s1.get(b"elsewhere"), None); - - // no collisions with other prefixes - let s2 = ReadonlyPrefixedStorage::new(&storage, b"fo"); - assert_eq!(s2.get(b"obar"), None); - } - - #[test] - fn readonly_prefixed_storage_multilevel_get() { - let mut storage = MockStorage::new(); - storage.set(b"\x00\x03foo\x00\x03barbaz", b"winner"); - - let bar = ReadonlyPrefixedStorage::multilevel(&storage, &[b"foo", b"bar"]); - assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec())); - assert_eq!(bar.get(b"elsewhere"), None); - } -} diff --git a/packages/multi-test/src/prefixed_storage/length_prefixed.rs b/packages/multi-test/src/prefixed_storage/length_prefixed.rs deleted file mode 100644 index 5d97b3b41..000000000 --- a/packages/multi-test/src/prefixed_storage/length_prefixed.rs +++ /dev/null @@ -1,176 +0,0 @@ -//! This module is an implemention of a namespacing scheme described -//! in https://github.com/webmaster128/key-namespacing#length-prefixed-keys -//! -//! Everything in this file is only responsible for building such keys -//! and is in no way specific to any kind of storage. - -/// Calculates the raw key prefix for a given namespace as documented -/// in https://github.com/webmaster128/key-namespacing#length-prefixed-keys -pub fn to_length_prefixed(namespace: &[u8]) -> Vec { - let mut out = Vec::with_capacity(namespace.len() + 2); - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - out -} - -/// Calculates the raw key prefix for a given nested namespace -/// as documented in https://github.com/webmaster128/key-namespacing#nesting -pub fn to_length_prefixed_nested(namespaces: &[&[u8]]) -> Vec { - let mut size = 0; - for &namespace in namespaces { - size += namespace.len() + 2; - } - - let mut out = Vec::with_capacity(size); - for &namespace in namespaces { - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - } - out -} - -/// Encodes the length of a given namespace as a 2 byte big endian encoded integer -fn encode_length(namespace: &[u8]) -> [u8; 2] { - if namespace.len() > 0xFFFF { - panic!("only supports namespaces up to length 0xFFFF") - } - let length_bytes = (namespace.len() as u32).to_be_bytes(); - [length_bytes[2], length_bytes[3]] -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn to_length_prefixed_works() { - assert_eq!(to_length_prefixed(b""), b"\x00\x00"); - assert_eq!(to_length_prefixed(b"a"), b"\x00\x01a"); - assert_eq!(to_length_prefixed(b"ab"), b"\x00\x02ab"); - assert_eq!(to_length_prefixed(b"abc"), b"\x00\x03abc"); - } - - #[test] - fn to_length_prefixed_works_for_long_prefix() { - let long_namespace1 = vec![0; 256]; - let prefix1 = to_length_prefixed(&long_namespace1); - assert_eq!(prefix1.len(), 256 + 2); - assert_eq!(&prefix1[0..2], b"\x01\x00"); - - let long_namespace2 = vec![0; 30000]; - let prefix2 = to_length_prefixed(&long_namespace2); - assert_eq!(prefix2.len(), 30000 + 2); - assert_eq!(&prefix2[0..2], b"\x75\x30"); - - let long_namespace3 = vec![0; 0xFFFF]; - let prefix3 = to_length_prefixed(&long_namespace3); - assert_eq!(prefix3.len(), 0xFFFF + 2); - assert_eq!(&prefix3[0..2], b"\xFF\xFF"); - } - - #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] - fn to_length_prefixed_panics_for_too_long_prefix() { - let limit = 0xFFFF; - let long_namespace = vec![0; limit + 1]; - to_length_prefixed(&long_namespace); - } - - #[test] - fn to_length_prefixed_calculates_capacity_correctly() { - // Those tests cannot guarantee the required capacity was calculated correctly before - // the vector allocation but increase the likelyhood of a proper implementation. - - let key = to_length_prefixed(b""); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed(b"h"); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed(b"hij"); - assert_eq!(key.capacity(), key.len()); - } - - #[test] - fn to_length_prefixed_nested_works() { - assert_eq!(to_length_prefixed_nested(&[]), b""); - assert_eq!(to_length_prefixed_nested(&[b""]), b"\x00\x00"); - assert_eq!(to_length_prefixed_nested(&[b"", b""]), b"\x00\x00\x00\x00"); - - assert_eq!(to_length_prefixed_nested(&[b"a"]), b"\x00\x01a"); - assert_eq!( - to_length_prefixed_nested(&[b"a", b"ab"]), - b"\x00\x01a\x00\x02ab" - ); - assert_eq!( - to_length_prefixed_nested(&[b"a", b"ab", b"abc"]), - b"\x00\x01a\x00\x02ab\x00\x03abc" - ); - } - - #[test] - fn to_length_prefixed_nested_allows_many_long_namespaces() { - // The 0xFFFF limit is for each namespace, not for the combination of them - - let long_namespace1 = vec![0xaa; 0xFFFD]; - let long_namespace2 = vec![0xbb; 0xFFFE]; - let long_namespace3 = vec![0xcc; 0xFFFF]; - - let prefix = - to_length_prefixed_nested(&[&long_namespace1, &long_namespace2, &long_namespace3]); - assert_eq!(&prefix[0..2], b"\xFF\xFD"); - assert_eq!(&prefix[2..(2 + 0xFFFD)], long_namespace1.as_slice()); - assert_eq!(&prefix[(2 + 0xFFFD)..(2 + 0xFFFD + 2)], b"\xFF\xFe"); - assert_eq!( - &prefix[(2 + 0xFFFD + 2)..(2 + 0xFFFD + 2 + 0xFFFE)], - long_namespace2.as_slice() - ); - assert_eq!( - &prefix[(2 + 0xFFFD + 2 + 0xFFFE)..(2 + 0xFFFD + 2 + 0xFFFE + 2)], - b"\xFF\xFf" - ); - assert_eq!( - &prefix[(2 + 0xFFFD + 2 + 0xFFFE + 2)..(2 + 0xFFFD + 2 + 0xFFFE + 2 + 0xFFFF)], - long_namespace3.as_slice() - ); - } - - #[test] - fn to_length_prefixed_nested_calculates_capacity_correctly() { - // Those tests cannot guarantee the required capacity was calculated correctly before - // the vector allocation but increase the likelyhood of a proper implementation. - - let key = to_length_prefixed_nested(&[]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b""]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a"]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a", b"bc"]); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed_nested(&[b"a", b"bc", b"def"]); - assert_eq!(key.capacity(), key.len()); - } - - #[test] - fn encode_length_works() { - assert_eq!(encode_length(b""), *b"\x00\x00"); - assert_eq!(encode_length(b"a"), *b"\x00\x01"); - assert_eq!(encode_length(b"aa"), *b"\x00\x02"); - assert_eq!(encode_length(b"aaa"), *b"\x00\x03"); - assert_eq!(encode_length(&vec![1; 255]), *b"\x00\xff"); - assert_eq!(encode_length(&vec![1; 256]), *b"\x01\x00"); - assert_eq!(encode_length(&vec![1; 12345]), *b"\x30\x39"); - assert_eq!(encode_length(&vec![1; 65535]), *b"\xff\xff"); - } - - #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] - fn encode_length_panics_for_large_values() { - encode_length(&vec![1; 65536]); - } -} diff --git a/packages/multi-test/src/prefixed_storage/namespace_helpers.rs b/packages/multi-test/src/prefixed_storage/namespace_helpers.rs deleted file mode 100644 index 2e69605de..000000000 --- a/packages/multi-test/src/prefixed_storage/namespace_helpers.rs +++ /dev/null @@ -1,220 +0,0 @@ -use cosmwasm_std::Storage; -#[cfg(feature = "iterator")] -use cosmwasm_std::{Order, Record}; - -pub(crate) fn get_with_prefix( - storage: &dyn Storage, - namespace: &[u8], - key: &[u8], -) -> Option> { - storage.get(&concat(namespace, key)) -} - -pub(crate) fn set_with_prefix( - storage: &mut dyn Storage, - namespace: &[u8], - key: &[u8], - value: &[u8], -) { - storage.set(&concat(namespace, key), value); -} - -pub(crate) fn remove_with_prefix(storage: &mut dyn Storage, namespace: &[u8], key: &[u8]) { - storage.remove(&concat(namespace, key)); -} - -#[inline] -fn concat(namespace: &[u8], key: &[u8]) -> Vec { - let mut k = namespace.to_vec(); - k.extend_from_slice(key); - k -} - -#[cfg(feature = "iterator")] -pub(crate) fn range_with_prefix<'a>( - storage: &'a dyn Storage, - namespace: &[u8], - start: Option<&[u8]>, - end: Option<&[u8]>, - order: Order, -) -> Box + 'a> { - // prepare start, end with prefix - let start = match start { - Some(s) => concat(namespace, s), - None => namespace.to_vec(), - }; - let end = match end { - Some(e) => concat(namespace, e), - // end is updating last byte by one - None => namespace_upper_bound(namespace), - }; - - // get iterator from storage - let base_iterator = storage.range(Some(&start), Some(&end), order); - - // make a copy for the closure to handle lifetimes safely - let prefix = namespace.to_vec(); - let mapped = base_iterator.map(move |(k, v)| (trim(&prefix, &k), v)); - Box::new(mapped) -} - -#[cfg(feature = "iterator")] -#[inline] -fn trim(namespace: &[u8], key: &[u8]) -> Vec { - key[namespace.len()..].to_vec() -} - -/// Returns a new vec of same length and last byte incremented by one -/// If last bytes are 255, we handle overflow up the chain. -/// If all bytes are 255, this returns wrong data - but that is never possible as a namespace -#[cfg(feature = "iterator")] -fn namespace_upper_bound(input: &[u8]) -> Vec { - let mut copy = input.to_vec(); - // zero out all trailing 255, increment first that is not such - for i in (0..input.len()).rev() { - if copy[i] == 255 { - copy[i] = 0; - } else { - copy[i] += 1; - break; - } - } - copy -} - -#[cfg(test)] -mod tests { - use super::super::length_prefixed::to_length_prefixed; - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn prefix_get_set() { - let mut storage = MockStorage::new(); - let prefix = to_length_prefixed(b"foo"); - - set_with_prefix(&mut storage, &prefix, b"bar", b"gotcha"); - let rfoo = get_with_prefix(&storage, &prefix, b"bar"); - assert_eq!(rfoo, Some(b"gotcha".to_vec())); - - // no collisions with other prefixes - let other_prefix = to_length_prefixed(b"fo"); - let collision = get_with_prefix(&storage, &other_prefix, b"obar"); - assert_eq!(collision, None); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_works() { - let mut storage = MockStorage::new(); - let prefix = to_length_prefixed(b"foo"); - let other_prefix = to_length_prefixed(b"food"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // ensure we get proper result from prefixed_range iterator - let mut iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); - let first = iter.next().unwrap(); - assert_eq!(first, (b"snowy".to_vec(), b"day".to_vec())); - let second = iter.next().unwrap(); - assert_eq!(second, (b"bar".to_vec(), b"none".to_vec())); - assert!(iter.next().is_none()); - - // ensure we get raw result from base range - let iter = storage.range(None, None, Order::Ascending); - assert_eq!(3, iter.count()); - - // foo comes first - let mut iter = storage.range(None, None, Order::Ascending); - let first = iter.next().unwrap(); - let expected_key = concat(&prefix, b"bar"); - assert_eq!(first, (expected_key, b"none".to_vec())); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_with_prefix_wrapover() { - let mut storage = MockStorage::new(); - // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) - let prefix = to_length_prefixed(b"f\xff\xff"); - let other_prefix = to_length_prefixed(b"f\xff\x44"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // ensure we get proper result from prefixed_range iterator - let iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"snowy".to_vec(), b"day".to_vec()), - (b"bar".to_vec(), b"none".to_vec()), - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_with_start_end_set() { - let mut storage = MockStorage::new(); - // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) - let prefix = to_length_prefixed(b"f\xff\xff"); - let other_prefix = to_length_prefixed(b"f\xff\x44"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // make sure start and end are applied properly - let res: Vec = - range_with_prefix(&storage, &prefix, Some(b"b"), Some(b"c"), Order::Ascending) - .collect(); - assert_eq!(res.len(), 1); - assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); - - // make sure start and end are applied properly - let res_count = range_with_prefix( - &storage, - &prefix, - Some(b"bas"), - Some(b"sno"), - Order::Ascending, - ) - .count(); - assert_eq!(res_count, 0); - - let res: Vec = - range_with_prefix(&storage, &prefix, Some(b"ant"), None, Order::Ascending).collect(); - assert_eq!(res.len(), 2); - assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); - assert_eq!(res[1], (b"snowy".to_vec(), b"day".to_vec())); - } - - #[test] - #[cfg(feature = "iterator")] - fn namespace_upper_bound_works() { - assert_eq!(namespace_upper_bound(b"bob"), b"boc".to_vec()); - assert_eq!(namespace_upper_bound(b"fo\xfe"), b"fo\xff".to_vec()); - assert_eq!(namespace_upper_bound(b"fo\xff"), b"fp\x00".to_vec()); - // multiple \xff roll over - assert_eq!( - namespace_upper_bound(b"fo\xff\xff\xff"), - b"fp\x00\x00\x00".to_vec() - ); - // \xff not at the end are ignored - assert_eq!(namespace_upper_bound(b"\xffabc"), b"\xffabd".to_vec()); - } -} diff --git a/packages/multi-test/src/staking.rs b/packages/multi-test/src/staking.rs deleted file mode 100644 index 043838f32..000000000 --- a/packages/multi-test/src/staking.rs +++ /dev/null @@ -1,1809 +0,0 @@ -use std::collections::BTreeSet; - -use anyhow::{anyhow, bail, Result as AnyResult}; -use schemars::JsonSchema; - -use cosmwasm_std::{ - coin, ensure, ensure_eq, to_binary, Addr, AllDelegationsResponse, AllValidatorsResponse, Api, - BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomQuery, Decimal, Delegation, - DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier, StakingMsg, - StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse, -}; -use cw_storage_plus::{Deque, Item, Map}; -use serde::{Deserialize, Serialize}; - -use crate::app::CosmosRouter; -use crate::executor::AppResponse; -use crate::prefixed_storage::{prefixed, prefixed_read}; -use crate::{BankSudo, Module}; - -// Contains some general staking parameters -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct StakingInfo { - /// The denominator of the staking token - pub bonded_denom: String, - /// Time between unbonding and receiving tokens in seconds - pub unbonding_time: u64, - /// Interest rate per year (60 * 60 * 24 * 365 seconds) - pub apr: Decimal, -} - -impl Default for StakingInfo { - fn default() -> Self { - StakingInfo { - bonded_denom: "TOKEN".to_string(), - unbonding_time: 60, - apr: Decimal::percent(10), - } - } -} - -/// The number of stake and rewards of this validator the staker has. These can be fractional in case of slashing. -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)] -struct Shares { - stake: Decimal, - rewards: Decimal, -} - -impl Shares { - /// Calculates the share of validator rewards that should be given to this staker. - pub fn share_of_rewards(&self, validator: &ValidatorInfo, rewards: Decimal) -> Decimal { - rewards * self.stake / validator.stake - } -} - -/// Holds some operational data about a validator -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -struct ValidatorInfo { - /// The stakers that have staked with this validator. - /// We need to track them for updating their rewards. - stakers: BTreeSet, - /// The whole stake of all stakers - stake: Uint128, - /// The block time when this validator's rewards were last update. This is needed for rewards calculation. - last_rewards_calculation: Timestamp, -} - -impl ValidatorInfo { - pub fn new(block_time: Timestamp) -> Self { - Self { - stakers: BTreeSet::new(), - stake: Uint128::zero(), - last_rewards_calculation: block_time, - } - } -} - -const STAKING_INFO: Item = Item::new("staking_info"); -/// (staker_addr, validator_addr) -> shares -const STAKES: Map<(&Addr, &Addr), Shares> = Map::new("stakes"); -const VALIDATOR_MAP: Map<&Addr, Validator> = Map::new("validator_map"); -/// Additional vec of validators, in case the `iterator` feature is disabled -const VALIDATORS: Deque = Deque::new("validators"); -/// Contains additional info for each validator -const VALIDATOR_INFO: Map<&Addr, ValidatorInfo> = Map::new("validator_info"); -/// The queue of unbonding operations. This is needed because unbonding has a waiting time. See [`StakeKeeper`] -const UNBONDING_QUEUE: Deque<(Addr, Timestamp, u128)> = Deque::new("unbonding_queue"); - -pub const NAMESPACE_STAKING: &[u8] = b"staking"; - -// We need to expand on this, but we will need this to properly test out staking -#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] -pub enum StakingSudo { - /// Slashes the given percentage of the validator's stake. - /// For now, you cannot slash retrospectively in tests. - Slash { - validator: String, - percentage: Decimal, - }, - /// Causes the unbonding queue to be processed. - /// This needs to be triggered manually, since there is no good place to do this right now. - /// In cosmos-sdk, this is done in `EndBlock`, but we don't have that here. - ProcessQueue {}, -} - -pub trait Staking: Module {} - -pub trait Distribution: Module {} - -pub struct StakeKeeper { - module_addr: Addr, -} - -impl Default for StakeKeeper { - fn default() -> Self { - Self::new() - } -} - -impl StakeKeeper { - pub fn new() -> Self { - StakeKeeper { - // The address of the staking module. This holds all staked tokens. - module_addr: Addr::unchecked("staking_module"), - } - } - - /// Provides some general parameters to the stake keeper - pub fn setup(&self, storage: &mut dyn Storage, staking_info: StakingInfo) -> AnyResult<()> { - let mut storage = prefixed(storage, NAMESPACE_STAKING); - - STAKING_INFO.save(&mut storage, &staking_info)?; - Ok(()) - } - - /// Add a new validator available for staking - pub fn add_validator( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - validator: Validator, - ) -> AnyResult<()> { - let mut storage = prefixed(storage, NAMESPACE_STAKING); - - let val_addr = api.addr_validate(&validator.address)?; - if VALIDATOR_MAP.may_load(&storage, &val_addr)?.is_some() { - bail!( - "Cannot add validator {}, since a validator with that address already exists", - val_addr - ); - } - - VALIDATOR_MAP.save(&mut storage, &val_addr, &validator)?; - VALIDATORS.push_back(&mut storage, &validator)?; - VALIDATOR_INFO.save(&mut storage, &val_addr, &ValidatorInfo::new(block.time))?; - Ok(()) - } - - fn get_staking_info(staking_storage: &dyn Storage) -> AnyResult { - Ok(STAKING_INFO.may_load(staking_storage)?.unwrap_or_default()) - } - - /// Returns the rewards of the given delegator at the given validator - pub fn get_rewards( - &self, - storage: &dyn Storage, - block: &BlockInfo, - delegator: &Addr, - validator: &Addr, - ) -> AnyResult> { - let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); - - let validator_obj = match self.get_validator(&staking_storage, validator)? { - Some(validator) => validator, - None => bail!("validator {} not found", validator), - }; - // calculate rewards using fixed ratio - let shares = match STAKES.load(&staking_storage, (delegator, validator)) { - Ok(stakes) => stakes, - Err(_) => { - return Ok(None); - } - }; - let validator_info = VALIDATOR_INFO.load(&staking_storage, validator)?; - - Self::get_rewards_internal( - &staking_storage, - block, - &shares, - &validator_obj, - &validator_info, - ) - .map(Some) - } - - fn get_rewards_internal( - staking_storage: &dyn Storage, - block: &BlockInfo, - shares: &Shares, - validator: &Validator, - validator_info: &ValidatorInfo, - ) -> AnyResult { - let staking_info = Self::get_staking_info(staking_storage)?; - - // calculate missing rewards without updating the validator to reduce rounding errors - let new_validator_rewards = Self::calculate_rewards( - block.time, - validator_info.last_rewards_calculation, - staking_info.apr, - validator.commission, - validator_info.stake, - ); - - // calculate the delegator's share of those - let delegator_rewards = - shares.rewards + shares.share_of_rewards(validator_info, new_validator_rewards); - - Ok(Coin { - denom: staking_info.bonded_denom, - amount: Uint128::new(1) * delegator_rewards, // multiplying by 1 to convert Decimal to Uint128 - }) - } - - /// Calculates the rewards that are due since the last calculation. - fn calculate_rewards( - current_time: Timestamp, - since: Timestamp, - interest_rate: Decimal, - validator_commission: Decimal, - stake: Uint128, - ) -> Decimal { - // calculate time since last update (in seconds) - let time_diff = current_time.minus_seconds(since.seconds()).seconds(); - - // using decimal here to reduce rounding error when calling this function a lot - let reward = Decimal::from_ratio(stake, 1u128) - * interest_rate - * Decimal::from_ratio(time_diff, 1u128) - / Decimal::from_ratio(60u128 * 60 * 24 * 365, 1u128); - let commission = reward * validator_commission; - - reward - commission - } - - /// Updates the staking reward for the given validator and their stakers - /// It saves the validator info and it's stakers, so make sure not to overwrite that. - /// Always call this to update rewards before changing anything that influences future rewards. - fn update_rewards( - api: &dyn Api, - staking_storage: &mut dyn Storage, - block: &BlockInfo, - validator: &Addr, - ) -> AnyResult<()> { - let staking_info = Self::get_staking_info(staking_storage)?; - - let mut validator_info = VALIDATOR_INFO - .may_load(staking_storage, validator)? - .ok_or_else(|| anyhow!("validator {} not found", validator))?; - - let validator_obj = VALIDATOR_MAP.load(staking_storage, validator)?; - - if validator_info.last_rewards_calculation >= block.time { - return Ok(()); - } - - let new_rewards = Self::calculate_rewards( - block.time, - validator_info.last_rewards_calculation, - staking_info.apr, - validator_obj.commission, - validator_info.stake, - ); - - // update validator info and delegators - if !new_rewards.is_zero() { - validator_info.last_rewards_calculation = block.time; - - // save updated validator - VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; - - let validator_addr = api.addr_validate(&validator_obj.address)?; - // update all delegators - for staker in validator_info.stakers.iter() { - STAKES.update( - staking_storage, - (staker, &validator_addr), - |shares| -> AnyResult<_> { - let mut shares = - shares.expect("all stakers in validator_info should exist"); - shares.rewards += shares.share_of_rewards(&validator_info, new_rewards); - Ok(shares) - }, - )?; - } - } - Ok(()) - } - - /// Returns the single validator with the given address (or `None` if there is no such validator) - fn get_validator( - &self, - staking_storage: &dyn Storage, - address: &Addr, - ) -> AnyResult> { - Ok(VALIDATOR_MAP.may_load(staking_storage, address)?) - } - - /// Returns all available validators - fn get_validators(&self, staking_storage: &dyn Storage) -> AnyResult> { - let res: Result<_, _> = VALIDATORS.iter(staking_storage)?.collect(); - Ok(res?) - } - - fn get_stake( - &self, - staking_storage: &dyn Storage, - account: &Addr, - validator: &Addr, - ) -> AnyResult> { - let shares = STAKES.may_load(staking_storage, (account, validator))?; - let staking_info = Self::get_staking_info(staking_storage)?; - - Ok(shares.map(|shares| { - Coin { - denom: staking_info.bonded_denom, - amount: Uint128::new(1) * shares.stake, // multiplying by 1 to convert Decimal to Uint128 - } - })) - } - - fn add_stake( - &self, - api: &dyn Api, - staking_storage: &mut dyn Storage, - block: &BlockInfo, - to_address: &Addr, - validator: &Addr, - amount: Coin, - ) -> AnyResult<()> { - self.validate_denom(staking_storage, &amount)?; - self.update_stake( - api, - staking_storage, - block, - to_address, - validator, - amount.amount, - false, - ) - } - - fn remove_stake( - &self, - api: &dyn Api, - staking_storage: &mut dyn Storage, - block: &BlockInfo, - from_address: &Addr, - validator: &Addr, - amount: Coin, - ) -> AnyResult<()> { - self.validate_denom(staking_storage, &amount)?; - self.update_stake( - api, - staking_storage, - block, - from_address, - validator, - amount.amount, - true, - ) - } - - fn update_stake( - &self, - api: &dyn Api, - staking_storage: &mut dyn Storage, - block: &BlockInfo, - delegator: &Addr, - validator: &Addr, - amount: impl Into, - sub: bool, - ) -> AnyResult<()> { - let amount = amount.into(); - - // update rewards for this validator - Self::update_rewards(api, staking_storage, block, validator)?; - - // now, we can update the stake of the delegator and validator - let mut validator_info = VALIDATOR_INFO - .may_load(staking_storage, validator)? - .unwrap_or_else(|| ValidatorInfo::new(block.time)); - let mut shares = STAKES - .may_load(staking_storage, (delegator, validator))? - .unwrap_or_default(); - let amount_dec = Decimal::from_ratio(amount, 1u128); - if sub { - if amount_dec > shares.stake { - bail!("insufficient stake"); - } - shares.stake -= amount_dec; - validator_info.stake = validator_info.stake.checked_sub(amount)?; - } else { - shares.stake += amount_dec; - validator_info.stake = validator_info.stake.checked_add(amount)?; - } - - // save updated values - if shares.stake.is_zero() { - // no more stake, so remove - STAKES.remove(staking_storage, (delegator, validator)); - validator_info.stakers.remove(delegator); - } else { - STAKES.save(staking_storage, (delegator, validator), &shares)?; - validator_info.stakers.insert(delegator.clone()); - } - // save updated validator info - VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; - - Ok(()) - } - - fn slash( - &self, - api: &dyn Api, - staking_storage: &mut dyn Storage, - block: &BlockInfo, - validator: &Addr, - percentage: Decimal, - ) -> AnyResult<()> { - // calculate rewards before slashing - Self::update_rewards(api, staking_storage, block, validator)?; - - // update stake of validator and stakers - let mut validator_info = VALIDATOR_INFO - .may_load(staking_storage, validator)? - .ok_or_else(|| anyhow!("validator {} not found", validator))?; - - let remaining_percentage = Decimal::one() - percentage; - validator_info.stake = validator_info.stake * remaining_percentage; - - // if the stake is completely gone, we clear all stakers and reinitialize the validator - if validator_info.stake.is_zero() { - // need to remove all stakes - for delegator in validator_info.stakers.iter() { - STAKES.remove(staking_storage, (delegator, validator)); - } - validator_info.stakers.clear(); - } else { - // otherwise we update all stakers - for delegator in validator_info.stakers.iter() { - STAKES.update( - staking_storage, - (delegator, validator), - |stake| -> AnyResult<_> { - let mut stake = stake.expect("all stakers in validator_info should exist"); - stake.stake *= remaining_percentage; - - Ok(stake) - }, - )?; - } - } - VALIDATOR_INFO.save(staking_storage, validator, &validator_info)?; - Ok(()) - } - - // Asserts that the given coin has the proper denominator - fn validate_denom(&self, staking_storage: &dyn Storage, amount: &Coin) -> AnyResult<()> { - let staking_info = Self::get_staking_info(staking_storage)?; - ensure_eq!( - amount.denom, - staking_info.bonded_denom, - anyhow!( - "cannot delegate coins of denominator {}, only of {}", - amount.denom, - staking_info.bonded_denom - ) - ); - Ok(()) - } - - // Asserts that the given coin has the proper denominator - fn validate_percentage(&self, percentage: Decimal) -> AnyResult<()> { - ensure!(percentage <= Decimal::one(), anyhow!("expected percentage")); - Ok(()) - } -} - -impl Staking for StakeKeeper {} - -impl Module for StakeKeeper { - type ExecT = StakingMsg; - type QueryT = StakingQuery; - type SudoT = StakingSudo; - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - msg: StakingMsg, - ) -> AnyResult { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); - match msg { - StakingMsg::Delegate { validator, amount } => { - let validator = api.addr_validate(&validator)?; - - // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L251-L256 - let events = vec![Event::new("delegate") - .add_attribute("validator", &validator) - .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) - .add_attribute("new_shares", amount.amount.to_string())]; // TODO: calculate shares? - self.add_stake( - api, - &mut staking_storage, - block, - &sender, - &validator, - amount.clone(), - )?; - // move money from sender account to this module (note we can control sender here) - if !amount.amount.is_zero() { - router.execute( - api, - storage, - block, - sender, - BankMsg::Send { - to_address: self.module_addr.to_string(), - amount: vec![amount], - } - .into(), - )?; - } - Ok(AppResponse { events, data: None }) - } - StakingMsg::Undelegate { validator, amount } => { - let validator = api.addr_validate(&validator)?; - self.validate_denom(&staking_storage, &amount)?; - - // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L378-L383 - let events = vec![Event::new("unbond") - .add_attribute("validator", &validator) - .add_attribute("amount", format!("{}{}", amount.amount, amount.denom)) - .add_attribute("completion_time", "2022-09-27T14:00:00+00:00")]; // TODO: actual date? - self.remove_stake( - api, - &mut staking_storage, - block, - &sender, - &validator, - amount.clone(), - )?; - // add tokens to unbonding queue - let staking_info = Self::get_staking_info(&staking_storage)?; - UNBONDING_QUEUE.push_back( - &mut staking_storage, - &( - sender.clone(), - block.time.plus_seconds(staking_info.unbonding_time), - amount.amount.u128(), - ), - )?; - Ok(AppResponse { events, data: None }) - } - StakingMsg::Redelegate { - src_validator, - dst_validator, - amount, - } => { - let src_validator = api.addr_validate(&src_validator)?; - let dst_validator = api.addr_validate(&dst_validator)?; - // see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L316-L322 - let events = vec![Event::new("redelegate") - .add_attribute("source_validator", &src_validator) - .add_attribute("destination_validator", &dst_validator) - .add_attribute("amount", format!("{}{}", amount.amount, amount.denom))]; - - self.remove_stake( - api, - &mut staking_storage, - block, - &sender, - &src_validator, - amount.clone(), - )?; - self.add_stake( - api, - &mut staking_storage, - block, - &sender, - &dst_validator, - amount, - )?; - - Ok(AppResponse { events, data: None }) - } - m => bail!("Unsupported staking message: {:?}", m), - } - } - - fn sudo( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: StakingSudo, - ) -> AnyResult { - match msg { - StakingSudo::Slash { - validator, - percentage, - } => { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); - let validator = api.addr_validate(&validator)?; - self.validate_percentage(percentage)?; - - self.slash(api, &mut staking_storage, block, &validator, percentage)?; - - Ok(AppResponse::default()) - } - StakingSudo::ProcessQueue {} => { - loop { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); - let front = UNBONDING_QUEUE.front(&staking_storage)?; - match front { - // assuming the queue is sorted by payout_at - Some((_, payout_at, _)) if payout_at <= block.time => { - // remove from queue - let (delegator, _, amount) = - UNBONDING_QUEUE.pop_front(&mut staking_storage)?.unwrap(); - - let staking_info = Self::get_staking_info(&staking_storage)?; - if amount > 0 { - router.execute( - api, - storage, - block, - self.module_addr.clone(), - BankMsg::Send { - to_address: delegator.into_string(), - amount: vec![coin(amount, &staking_info.bonded_denom)], - } - .into(), - )?; - } - } - _ => break, - } - } - Ok(AppResponse::default()) - } - } - } - - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - _querier: &dyn Querier, - block: &BlockInfo, - request: StakingQuery, - ) -> AnyResult { - let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); - match request { - StakingQuery::BondedDenom {} => Ok(to_binary(&BondedDenomResponse { - denom: Self::get_staking_info(&staking_storage)?.bonded_denom, - })?), - StakingQuery::AllDelegations { delegator } => { - let delegator = api.addr_validate(&delegator)?; - let validators = self.get_validators(&staking_storage)?; - - let res: AnyResult> = validators - .into_iter() - .filter_map(|validator| { - let delegator = delegator.clone(); - let amount = self - .get_stake( - &staking_storage, - &delegator, - &Addr::unchecked(&validator.address), - ) - .transpose()?; - - Some(amount.map(|amount| Delegation { - delegator, - validator: validator.address, - amount, - })) - }) - .collect(); - - Ok(to_binary(&AllDelegationsResponse { delegations: res? })?) - } - StakingQuery::Delegation { - delegator, - validator, - } => { - let validator_addr = Addr::unchecked(&validator); - let validator_obj = match self.get_validator(&staking_storage, &validator_addr)? { - Some(validator) => validator, - None => bail!("non-existent validator {}", validator), - }; - let delegator = api.addr_validate(&delegator)?; - - let shares = match STAKES.load(&staking_storage, (&delegator, &validator_addr)) { - Ok(stakes) => stakes, - Err(_) => { - let response = DelegationResponse { delegation: None }; - return Ok(to_binary(&response)?); - } - }; - let validator_info = VALIDATOR_INFO.load(&staking_storage, &validator_addr)?; - let reward = Self::get_rewards_internal( - &staking_storage, - block, - &shares, - &validator_obj, - &validator_info, - )?; - let staking_info = Self::get_staking_info(&staking_storage)?; - let amount = coin( - (shares.stake * Uint128::new(1)).u128(), - staking_info.bonded_denom, - ); - let full_delegation_response = DelegationResponse { - delegation: Some(FullDelegation { - delegator, - validator, - amount: amount.clone(), - can_redelegate: amount, // TODO: not implemented right now - accumulated_rewards: if reward.amount.is_zero() { - vec![] - } else { - vec![reward] - }, - }), - }; - - let res = to_binary(&full_delegation_response)?; - Ok(res) - } - StakingQuery::AllValidators {} => Ok(to_binary(&AllValidatorsResponse { - validators: self.get_validators(&staking_storage)?, - })?), - StakingQuery::Validator { address } => Ok(to_binary(&ValidatorResponse { - validator: self.get_validator(&staking_storage, &Addr::unchecked(address))?, - })?), - q => bail!("Unsupported staking sudo message: {:?}", q), - } - } -} - -#[derive(Default)] -pub struct DistributionKeeper {} - -impl DistributionKeeper { - pub fn new() -> Self { - DistributionKeeper {} - } - - /// Removes all rewards from the given (delegator, validator) pair and returns the amount - pub fn remove_rewards( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - block: &BlockInfo, - delegator: &Addr, - validator: &Addr, - ) -> AnyResult { - let mut staking_storage = prefixed(storage, NAMESPACE_STAKING); - // update the validator and staker rewards - StakeKeeper::update_rewards(api, &mut staking_storage, block, validator)?; - - // load updated rewards for delegator - let mut shares = STAKES.load(&staking_storage, (delegator, validator))?; - let rewards = Uint128::new(1) * shares.rewards; // convert to Uint128 - - // remove rewards from delegator - shares.rewards = Decimal::zero(); - STAKES.save(&mut staking_storage, (delegator, validator), &shares)?; - - Ok(rewards) - } -} - -impl Distribution for DistributionKeeper {} - -impl Module for DistributionKeeper { - type ExecT = DistributionMsg; - type QueryT = Empty; - type SudoT = Empty; - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - msg: DistributionMsg, - ) -> AnyResult { - match msg { - DistributionMsg::WithdrawDelegatorReward { validator } => { - let validator_addr = api.addr_validate(&validator)?; - - let rewards = self.remove_rewards(api, storage, block, &sender, &validator_addr)?; - - let staking_storage = prefixed_read(storage, NAMESPACE_STAKING); - let staking_info = StakeKeeper::get_staking_info(&staking_storage)?; - // directly mint rewards to delegator - router.sudo( - api, - storage, - block, - BankSudo::Mint { - to_address: sender.to_string(), - amount: vec![Coin { - amount: rewards, - denom: staking_info.bonded_denom.clone(), - }], - } - .into(), - )?; - - let events = vec![Event::new("withdraw_delegator_reward") - .add_attribute("validator", &validator) - .add_attribute("sender", &sender) - .add_attribute( - "amount", - format!("{}{}", rewards, staking_info.bonded_denom), - )]; - Ok(AppResponse { events, data: None }) - } - m => bail!("Unsupported distribution message: {:?}", m), - } - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn CosmosRouter, - _block: &BlockInfo, - _msg: Empty, - ) -> AnyResult { - bail!("Something went wrong - Distribution doesn't have sudo messages") - } - - fn query( - &self, - _api: &dyn Api, - _storage: &dyn Storage, - _querier: &dyn Querier, - _block: &BlockInfo, - _request: Empty, - ) -> AnyResult { - bail!("Something went wrong - Distribution doesn't have query messages") - } -} - -#[cfg(test)] -mod test { - use crate::{app::MockRouter, BankKeeper, FailingModule, Router, WasmKeeper}; - - use super::*; - - use cosmwasm_std::{ - from_slice, - testing::{mock_env, MockApi, MockStorage}, - BalanceResponse, BankQuery, - }; - - /// Type alias for default build `Router` to make its reference in typical scenario - type BasicRouter = Router< - BankKeeper, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - >; - - fn mock_router() -> BasicRouter { - Router { - wasm: WasmKeeper::new(), - bank: BankKeeper::new(), - custom: FailingModule::new(), - staking: StakeKeeper::new(), - distribution: DistributionKeeper::new(), - } - } - - fn setup_test_env( - apr: Decimal, - validator_commission: Decimal, - ) -> (MockApi, MockStorage, BasicRouter, BlockInfo, Addr) { - let api = MockApi::default(); - let router = mock_router(); - let mut store = MockStorage::new(); - let block = mock_env().block; - - let validator = api.addr_validate("testvaloper1").unwrap(); - - router - .staking - .setup( - &mut store, - StakingInfo { - bonded_denom: "TOKEN".to_string(), - unbonding_time: 60, - apr, - }, - ) - .unwrap(); - - // add validator - let valoper1 = Validator { - address: "testvaloper1".to_string(), - commission: validator_commission, - max_commission: Decimal::percent(100), - max_change_rate: Decimal::percent(1), - }; - router - .staking - .add_validator(&api, &mut store, &block, valoper1) - .unwrap(); - - (api, store, router, block, validator) - } - - #[test] - fn add_get_validators() { - let api = MockApi::default(); - let mut store = MockStorage::new(); - let stake = StakeKeeper::default(); - let block = mock_env().block; - - // add validator - let valoper1 = Validator { - address: "testvaloper1".to_string(), - commission: Decimal::percent(10), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }; - stake - .add_validator(&api, &mut store, &block, valoper1.clone()) - .unwrap(); - - // get it - let staking_storage = prefixed_read(&store, NAMESPACE_STAKING); - let val = stake - .get_validator( - &staking_storage, - &api.addr_validate("testvaloper1").unwrap(), - ) - .unwrap() - .unwrap(); - assert_eq!(val, valoper1); - - // try to add with same address - let valoper1_fake = Validator { - address: "testvaloper1".to_string(), - commission: Decimal::percent(1), - max_commission: Decimal::percent(10), - max_change_rate: Decimal::percent(100), - }; - stake - .add_validator(&api, &mut store, &block, valoper1_fake) - .unwrap_err(); - - // should still be original value - let staking_storage = prefixed_read(&store, NAMESPACE_STAKING); - let val = stake - .get_validator( - &staking_storage, - &api.addr_validate("testvaloper1").unwrap(), - ) - .unwrap() - .unwrap(); - assert_eq!(val, valoper1); - } - - #[test] - fn validator_slashing() { - let api = MockApi::default(); - let router = MockRouter::default(); - let mut store = MockStorage::new(); - let stake = StakeKeeper::new(); - let block = mock_env().block; - - let delegator = Addr::unchecked("delegator"); - let validator = api.addr_validate("testvaloper1").unwrap(); - - // add validator - let valoper1 = Validator { - address: "testvaloper1".to_string(), - commission: Decimal::percent(10), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }; - stake - .add_validator(&api, &mut store, &block, valoper1) - .unwrap(); - - // stake 100 tokens - let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - stake - .add_stake( - &api, - &mut staking_storage, - &block, - &delegator, - &validator, - coin(100, "TOKEN"), - ) - .unwrap(); - - // slash 50% - stake - .sudo( - &api, - &mut store, - &router, - &block, - StakingSudo::Slash { - validator: "testvaloper1".to_string(), - percentage: Decimal::percent(50), - }, - ) - .unwrap(); - - // check stake - let staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - let stake_left = stake - .get_stake(&staking_storage, &delegator, &validator) - .unwrap(); - assert_eq!( - stake_left.unwrap().amount.u128(), - 50, - "should have slashed 50%" - ); - - // slash all - stake - .sudo( - &api, - &mut store, - &router, - &block, - StakingSudo::Slash { - validator: "testvaloper1".to_string(), - percentage: Decimal::percent(100), - }, - ) - .unwrap(); - - // check stake - let staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - let stake_left = stake - .get_stake(&staking_storage, &delegator, &validator) - .unwrap(); - assert_eq!(stake_left, None, "should have slashed whole stake"); - } - - #[test] - fn rewards_work_for_single_delegator() { - let (api, mut store, router, mut block, validator) = - setup_test_env(Decimal::percent(10), Decimal::percent(10)); - let stake = &router.staking; - let distr = &router.distribution; - let delegator = Addr::unchecked("delegator"); - - let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - // stake 200 tokens - stake - .add_stake( - &api, - &mut staking_storage, - &block, - &delegator, - &validator, - coin(200, "TOKEN"), - ) - .unwrap(); - - // wait 1/2 year - block.time = block.time.plus_seconds(60 * 60 * 24 * 365 / 2); - - // should now have 200 * 10% / 2 - 10% commission = 9 tokens reward - let rewards = stake - .get_rewards(&store, &block, &delegator, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 9, "should have 9 tokens reward"); - - // withdraw rewards - distr - .execute( - &api, - &mut store, - &router, - &block, - delegator.clone(), - DistributionMsg::WithdrawDelegatorReward { - validator: validator.to_string(), - }, - ) - .unwrap(); - - // should have no rewards left - let rewards = stake - .get_rewards(&store, &block, &delegator, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 0); - - // wait another 1/2 year - block.time = block.time.plus_seconds(60 * 60 * 24 * 365 / 2); - // should now have 9 tokens again - let rewards = stake - .get_rewards(&store, &block, &delegator, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 9); - } - - #[test] - fn rewards_work_for_multiple_delegators() { - let (api, mut store, router, mut block, validator) = - setup_test_env(Decimal::percent(10), Decimal::percent(10)); - let stake = &router.staking; - let distr = &router.distribution; - let bank = &router.bank; - let delegator1 = Addr::unchecked("delegator1"); - let delegator2 = Addr::unchecked("delegator2"); - - let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - - // add 100 stake to delegator1 and 200 to delegator2 - stake - .add_stake( - &api, - &mut staking_storage, - &block, - &delegator1, - &validator, - coin(100, "TOKEN"), - ) - .unwrap(); - stake - .add_stake( - &api, - &mut staking_storage, - &block, - &delegator2, - &validator, - coin(200, "TOKEN"), - ) - .unwrap(); - - // wait 1 year - block.time = block.time.plus_seconds(60 * 60 * 24 * 365); - - // delegator1 should now have 100 * 10% - 10% commission = 9 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator1, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 9); - - // delegator2 should now have 200 * 10% - 10% commission = 18 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator2, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 18); - - // delegator1 stakes 100 more - let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - stake - .add_stake( - &api, - &mut staking_storage, - &block, - &delegator1, - &validator, - coin(100, "TOKEN"), - ) - .unwrap(); - - // wait another year - block.time = block.time.plus_seconds(60 * 60 * 24 * 365); - - // delegator1 should now have 9 + 200 * 10% - 10% commission = 27 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator1, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 27); - - // delegator2 should now have 18 + 200 * 10% - 10% commission = 36 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator2, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 36); - - // delegator2 unstakes 100 (has 100 left after that) - let mut staking_storage = prefixed(&mut store, NAMESPACE_STAKING); - stake - .remove_stake( - &api, - &mut staking_storage, - &block, - &delegator2, - &validator, - coin(100, "TOKEN"), - ) - .unwrap(); - - // and delegator1 withdraws rewards - distr - .execute( - &api, - &mut store, - &router, - &block, - delegator1.clone(), - DistributionMsg::WithdrawDelegatorReward { - validator: validator.to_string(), - }, - ) - .unwrap(); - - let balance: BalanceResponse = from_slice( - &bank - .query( - &api, - &store, - &router.querier(&api, &store, &block), - &block, - BankQuery::Balance { - address: delegator1.to_string(), - denom: "TOKEN".to_string(), - }, - ) - .unwrap(), - ) - .unwrap(); - assert_eq!( - balance.amount.amount.u128(), - 27, - "withdraw should change bank balance" - ); - let rewards = stake - .get_rewards(&store, &block, &delegator1, &validator) - .unwrap() - .unwrap(); - assert_eq!( - rewards.amount.u128(), - 0, - "withdraw should reduce rewards to 0" - ); - - // wait another year - block.time = block.time.plus_seconds(60 * 60 * 24 * 365); - - // delegator1 should now have 0 + 200 * 10% - 10% commission = 18 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator1, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 18); - - // delegator2 should now have 36 + 100 * 10% - 10% commission = 45 tokens - let rewards = stake - .get_rewards(&store, &block, &delegator2, &validator) - .unwrap() - .unwrap(); - assert_eq!(rewards.amount.u128(), 45); - } - - mod msg { - use cosmwasm_std::{from_slice, Addr, BondedDenomResponse, Decimal, StakingQuery}; - use serde::de::DeserializeOwned; - - use super::*; - - // shortens tests a bit - struct TestEnv { - api: MockApi, - store: MockStorage, - router: BasicRouter, - block: BlockInfo, - } - - impl TestEnv { - fn wrap(tuple: (MockApi, MockStorage, BasicRouter, BlockInfo, Addr)) -> (Self, Addr) { - ( - Self { - api: tuple.0, - store: tuple.1, - router: tuple.2, - block: tuple.3, - }, - tuple.4, - ) - } - } - - fn execute_stake( - env: &mut TestEnv, - sender: Addr, - msg: StakingMsg, - ) -> AnyResult { - env.router.staking.execute( - &env.api, - &mut env.store, - &env.router, - &env.block, - sender, - msg, - ) - } - - fn query_stake(env: &TestEnv, msg: StakingQuery) -> AnyResult { - Ok(from_slice(&env.router.staking.query( - &env.api, - &env.store, - &env.router.querier(&env.api, &env.store, &env.block), - &env.block, - msg, - )?)?) - } - - fn execute_distr( - env: &mut TestEnv, - sender: Addr, - msg: DistributionMsg, - ) -> AnyResult { - env.router.distribution.execute( - &env.api, - &mut env.store, - &env.router, - &env.block, - sender, - msg, - ) - } - - fn query_bank(env: &TestEnv, msg: BankQuery) -> AnyResult { - Ok(from_slice(&env.router.bank.query( - &env.api, - &env.store, - &env.router.querier(&env.api, &env.store, &env.block), - &env.block, - msg, - )?)?) - } - - fn assert_balances(env: &TestEnv, balances: impl IntoIterator) { - for (addr, amount) in balances { - let balance: BalanceResponse = query_bank( - env, - BankQuery::Balance { - address: addr.to_string(), - denom: "TOKEN".to_string(), - }, - ) - .unwrap(); - assert_eq!(balance.amount.amount.u128(), amount); - } - } - - #[test] - fn execute() { - // test all execute msgs - let (mut test_env, validator1) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - - let delegator1 = Addr::unchecked("delegator1"); - - // fund delegator1 account - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator1, vec![coin(1000, "TOKEN")]) - .unwrap(); - - // add second validator - let validator2 = Addr::unchecked("validator2"); - test_env - .router - .staking - .add_validator( - &test_env.api, - &mut test_env.store, - &test_env.block, - Validator { - address: validator2.to_string(), - commission: Decimal::zero(), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }, - ) - .unwrap(); - - // delegate 100 tokens to validator1 - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Delegate { - validator: validator1.to_string(), - amount: coin(100, "TOKEN"), - }, - ) - .unwrap(); - - // should now have 100 tokens less - assert_balances(&test_env, vec![(delegator1.clone(), 900)]); - - // wait a year - test_env.block.time = test_env.block.time.plus_seconds(60 * 60 * 24 * 365); - - // withdraw rewards - execute_distr( - &mut test_env, - delegator1.clone(), - DistributionMsg::WithdrawDelegatorReward { - validator: validator1.to_string(), - }, - ) - .unwrap(); - - // redelegate to validator2 - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Redelegate { - src_validator: validator1.to_string(), - dst_validator: validator2.to_string(), - amount: coin(100, "TOKEN"), - }, - ) - .unwrap(); - - // should have same amount as before - assert_balances( - &test_env, - vec![(delegator1.clone(), 900 + 100 / 10 * 9 / 10)], - ); - - let delegations: AllDelegationsResponse = query_stake( - &test_env, - StakingQuery::AllDelegations { - delegator: delegator1.to_string(), - }, - ) - .unwrap(); - assert_eq!( - delegations.delegations, - [Delegation { - delegator: delegator1.clone(), - validator: validator2.to_string(), - amount: coin(100, "TOKEN"), - }] - ); - - // undelegate all tokens - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Undelegate { - validator: validator2.to_string(), - amount: coin(100, "TOKEN"), - }, - ) - .unwrap(); - - // wait for unbonding period (60 seconds in default config) - test_env.block.time = test_env.block.time.plus_seconds(60); - - // need to manually cause queue to get processed - test_env - .router - .staking - .sudo( - &test_env.api, - &mut test_env.store, - &test_env.router, - &test_env.block, - StakingSudo::ProcessQueue {}, - ) - .unwrap(); - - // check bank balance - assert_balances( - &test_env, - vec![(delegator1.clone(), 1000 + 100 / 10 * 9 / 10)], - ); - } - - #[test] - fn cannot_steal() { - let (mut test_env, validator1) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - - let delegator1 = Addr::unchecked("delegator1"); - - // fund delegator1 account - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "TOKEN")]) - .unwrap(); - - // delegate 100 tokens to validator1 - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Delegate { - validator: validator1.to_string(), - amount: coin(100, "TOKEN"), - }, - ) - .unwrap(); - - // undelegate more tokens than we have - let e = execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Undelegate { - validator: validator1.to_string(), - amount: coin(200, "TOKEN"), - }, - ) - .unwrap_err(); - - assert_eq!(e.to_string(), "insufficient stake"); - - // add second validator - let validator2 = Addr::unchecked("validator2"); - test_env - .router - .staking - .add_validator( - &test_env.api, - &mut test_env.store, - &test_env.block, - Validator { - address: validator2.to_string(), - commission: Decimal::zero(), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }, - ) - .unwrap(); - - // redelegate more tokens than we have - let e = execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Redelegate { - src_validator: validator1.to_string(), - dst_validator: validator2.to_string(), - amount: coin(200, "TOKEN"), - }, - ) - .unwrap_err(); - assert_eq!(e.to_string(), "insufficient stake"); - } - - #[test] - fn denom_validation() { - let (mut test_env, validator) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - - let delegator1 = Addr::unchecked("delegator1"); - - // fund delegator1 account - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "FAKE")]) - .unwrap(); - - // try to delegate 100 to validator1 - let e = execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Delegate { - validator: validator.to_string(), - amount: coin(100, "FAKE"), - }, - ) - .unwrap_err(); - - assert_eq!( - e.to_string(), - "cannot delegate coins of denominator FAKE, only of TOKEN", - ); - } - - #[test] - fn cannot_slash_nonexistent() { - let (mut test_env, _) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - - let delegator1 = Addr::unchecked("delegator1"); - - // fund delegator1 account - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator1, vec![coin(100, "FAKE")]) - .unwrap(); - - // try to delegate 100 to validator1 - let e = test_env - .router - .staking - .sudo( - &test_env.api, - &mut test_env.store, - &test_env.router, - &test_env.block, - StakingSudo::Slash { - validator: "nonexistingvaloper".to_string(), - percentage: Decimal::percent(50), - }, - ) - .unwrap_err(); - assert_eq!(e.to_string(), "validator nonexistingvaloper not found"); - } - - #[test] - fn zero_staking_allowed() { - let (mut test_env, validator) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - - let delegator = Addr::unchecked("delegator1"); - - // delegate 0 - execute_stake( - &mut test_env, - delegator.clone(), - StakingMsg::Delegate { - validator: validator.to_string(), - amount: coin(0, "TOKEN"), - }, - ) - .unwrap(); - - // undelegate 0 - execute_stake( - &mut test_env, - delegator, - StakingMsg::Undelegate { - validator: validator.to_string(), - amount: coin(0, "TOKEN"), - }, - ) - .unwrap(); - } - - #[test] - fn query_staking() { - // run all staking queries - let (mut test_env, validator1) = - TestEnv::wrap(setup_test_env(Decimal::percent(10), Decimal::percent(10))); - let delegator1 = Addr::unchecked("delegator1"); - let delegator2 = Addr::unchecked("delegator2"); - - // init balances - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator1, vec![coin(260, "TOKEN")]) - .unwrap(); - test_env - .router - .bank - .init_balance(&mut test_env.store, &delegator2, vec![coin(150, "TOKEN")]) - .unwrap(); - - // add another validator - let validator2 = test_env.api.addr_validate("testvaloper2").unwrap(); - let valoper2 = Validator { - address: "testvaloper2".to_string(), - commission: Decimal::percent(0), - max_commission: Decimal::percent(1), - max_change_rate: Decimal::percent(1), - }; - test_env - .router - .staking - .add_validator( - &test_env.api, - &mut test_env.store, - &test_env.block, - valoper2.clone(), - ) - .unwrap(); - - // query validators - let valoper1: ValidatorResponse = query_stake( - &test_env, - StakingQuery::Validator { - address: validator1.to_string(), - }, - ) - .unwrap(); - let validators: AllValidatorsResponse = - query_stake(&test_env, StakingQuery::AllValidators {}).unwrap(); - assert_eq!( - validators.validators, - [valoper1.validator.unwrap(), valoper2] - ); - // query non-existent validator - let response = query_stake::( - &test_env, - StakingQuery::Validator { - address: "notvaloper".to_string(), - }, - ) - .unwrap(); - assert_eq!(response.validator, None); - - // query bonded denom - let response: BondedDenomResponse = - query_stake(&test_env, StakingQuery::BondedDenom {}).unwrap(); - assert_eq!(response.denom, "TOKEN"); - - // delegate some tokens with delegator1 and delegator2 - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Delegate { - validator: validator1.to_string(), - amount: coin(100, "TOKEN"), - }, - ) - .unwrap(); - execute_stake( - &mut test_env, - delegator1.clone(), - StakingMsg::Delegate { - validator: validator2.to_string(), - amount: coin(160, "TOKEN"), - }, - ) - .unwrap(); - execute_stake( - &mut test_env, - delegator2.clone(), - StakingMsg::Delegate { - validator: validator1.to_string(), - amount: coin(150, "TOKEN"), - }, - ) - .unwrap(); - - // query all delegations - let response1: AllDelegationsResponse = query_stake( - &test_env, - StakingQuery::AllDelegations { - delegator: delegator1.to_string(), - }, - ) - .unwrap(); - assert_eq!( - response1.delegations, - vec![ - Delegation { - delegator: delegator1.clone(), - validator: validator1.to_string(), - amount: coin(100, "TOKEN"), - }, - Delegation { - delegator: delegator1.clone(), - validator: validator2.to_string(), - amount: coin(160, "TOKEN"), - }, - ] - ); - let response2: DelegationResponse = query_stake( - &test_env, - StakingQuery::Delegation { - delegator: delegator2.to_string(), - validator: validator1.to_string(), - }, - ) - .unwrap(); - assert_eq!( - response2.delegation.unwrap(), - FullDelegation { - delegator: delegator2.clone(), - validator: validator1.to_string(), - amount: coin(150, "TOKEN"), - accumulated_rewards: vec![], - can_redelegate: coin(150, "TOKEN"), - }, - ); - } - } -} diff --git a/packages/multi-test/src/test_helpers.rs b/packages/multi-test/src/test_helpers.rs deleted file mode 100644 index cb551197b..000000000 --- a/packages/multi-test/src/test_helpers.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![cfg(test)] -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cw_storage_plus::Item; - -pub mod contracts; - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct EmptyMsg {} - -/// This is just a demo place so we can test custom message handling -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[serde(rename = "snake_case")] -pub enum CustomMsg { - SetName { name: String }, - SetAge { age: u32 }, -} - -const COUNT: Item = Item::new("count"); diff --git a/packages/multi-test/src/test_helpers/contracts.rs b/packages/multi-test/src/test_helpers/contracts.rs deleted file mode 100644 index 68babbf84..000000000 --- a/packages/multi-test/src/test_helpers/contracts.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Module for simple contracts to be used in tests - -pub mod caller; -pub mod echo; -pub mod error; -pub mod hackatom; -pub mod payout; -pub mod reflect; diff --git a/packages/multi-test/src/test_helpers/contracts/caller.rs b/packages/multi-test/src/test_helpers/contracts/caller.rs deleted file mode 100644 index 92367a3de..000000000 --- a/packages/multi-test/src/test_helpers/contracts/caller.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::fmt; - -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, SubMsg, WasmMsg}; -use schemars::JsonSchema; - -use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; - -fn instantiate( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - Ok(Response::default()) -} - -fn execute( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: WasmMsg, -) -> Result { - let message = SubMsg::new(msg); - - Ok(Response::new().add_submessage(message)) -} - -fn query(_deps: Deps, _env: Env, _msg: EmptyMsg) -> Result { - Err(StdError::generic_err( - "query not implemented for the `caller` contract", - )) -} - -pub fn contract() -> Box> -where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, -{ - let contract = ContractWrapper::new_with_empty(execute, instantiate, query); - Box::new(contract) -} diff --git a/packages/multi-test/src/test_helpers/contracts/echo.rs b/packages/multi-test/src/test_helpers/contracts/echo.rs deleted file mode 100644 index fb87602a6..000000000 --- a/packages/multi-test/src/test_helpers/contracts/echo.rs +++ /dev/null @@ -1,140 +0,0 @@ -//! Very simple echoing contract which just returns incomming string if any, but performming subcall of -//! given message to test response. -//! -//! Additionally it bypass all events and attributes send to it - -use cosmwasm_std::{ - to_binary, Attribute, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Reply, Response, - StdError, SubMsg, SubMsgResponse, SubMsgResult, -}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; - -use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; -use schemars::JsonSchema; -use std::fmt::Debug; - -use cw_utils::{parse_execute_response_data, parse_instantiate_response_data}; -use derivative::Derivative; - -// Choosing a reply id less than ECHO_EXECUTE_BASE_ID indicates an Instantiate message reply by convention. -// An Execute message reply otherwise. -pub(crate) const EXECUTE_REPLY_BASE_ID: u64 = i64::MAX as u64; - -#[derive(Debug, Clone, Serialize, Deserialize, Derivative)] -#[derivative(Default(bound = "", new = "true"))] -pub struct Message -where - ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, -{ - pub data: Option, - pub sub_msg: Vec>, - pub attributes: Vec, - pub events: Vec, -} - -// This can take some data... but happy to accept {} -#[derive(Debug, Clone, Serialize, Deserialize, Derivative)] -#[derivative(Default(bound = "", new = "true"))] -pub struct InitMessage -where - ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, -{ - pub data: Option, - pub sub_msg: Option>>, -} - -#[allow(clippy::unnecessary_wraps)] -fn instantiate( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InitMessage, -) -> Result, StdError> -where - ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, -{ - let mut res = Response::new(); - if let Some(data) = msg.data { - res = res.set_data(data.into_bytes()); - } - if let Some(msgs) = msg.sub_msg { - res = res.add_submessages(msgs); - } - Ok(res) -} - -#[allow(clippy::unnecessary_wraps)] -fn execute( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: Message, -) -> Result, StdError> -where - ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, -{ - let mut resp = Response::new(); - - if let Some(data) = msg.data { - resp = resp.set_data(data.into_bytes()); - } - - Ok(resp - .add_submessages(msg.sub_msg) - .add_attributes(msg.attributes) - .add_events(msg.events)) -} - -fn query(_deps: Deps, _env: Env, msg: EmptyMsg) -> Result { - to_binary(&msg) -} - -#[allow(clippy::unnecessary_wraps)] -fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result, StdError> -where - ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, -{ - let res = Response::new(); - if let Reply { - id, - result: SubMsgResult::Ok(SubMsgResponse { - data: Some(data), .. - }), - } = msg - { - // We parse out the WasmMsg::Execute wrapper... - // TODO: Handle all of Execute, Instantiate, and BankMsg replies differently. - let parsed_data = if id < EXECUTE_REPLY_BASE_ID { - parse_instantiate_response_data(data.as_slice()) - .map_err(|e| StdError::generic_err(e.to_string()))? - .data - } else { - parse_execute_response_data(data.as_slice()) - .map_err(|e| StdError::generic_err(e.to_string()))? - .data - }; - - if let Some(data) = parsed_data { - Ok(res.set_data(data)) - } else { - Ok(res) - } - } else { - Ok(res) - } -} - -pub fn contract() -> Box> { - let contract = ContractWrapper::new(execute::, instantiate::, query) - .with_reply(reply::); - Box::new(contract) -} - -pub fn custom_contract() -> Box> -where - C: Clone + Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, -{ - let contract = - ContractWrapper::new(execute::, instantiate::, query).with_reply(reply::); - Box::new(contract) -} diff --git a/packages/multi-test/src/test_helpers/contracts/error.rs b/packages/multi-test/src/test_helpers/contracts/error.rs deleted file mode 100644 index e707e80d6..000000000 --- a/packages/multi-test/src/test_helpers/contracts/error.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::fmt; - -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError}; -use schemars::JsonSchema; - -use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; - -fn instantiate_err( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - Err(StdError::generic_err("Init failed")) -} - -fn instantiate_ok( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - Ok(Response::default()) -} - -fn execute( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - Err(StdError::generic_err("Handle failed")) -} - -fn query(_deps: Deps, _env: Env, _msg: EmptyMsg) -> Result { - Err(StdError::generic_err("Query failed")) -} - -pub fn contract(instantiable: bool) -> Box> -where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, -{ - let contract = if instantiable { - ContractWrapper::new_with_empty(execute, instantiate_ok, query) - } else { - ContractWrapper::new_with_empty(execute, instantiate_err, query) - }; - Box::new(contract) -} diff --git a/packages/multi-test/src/test_helpers/contracts/hackatom.rs b/packages/multi-test/src/test_helpers/contracts/hackatom.rs deleted file mode 100644 index 7ceabbd61..000000000 --- a/packages/multi-test/src/test_helpers/contracts/hackatom.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! Simplified contract which when executed releases the funds to beneficiary - -use cosmwasm_std::{ - to_binary, BankMsg, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdError, -}; -use cw_storage_plus::Item; -use serde::{Deserialize, Serialize}; - -use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; -use schemars::JsonSchema; -use std::fmt; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct InstantiateMsg { - pub beneficiary: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MigrateMsg { - // just use some other string so we see there are other types - pub new_guy: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - // returns InstantiateMsg - Beneficiary {}, -} - -const HACKATOM: Item = Item::new("hackatom"); - -fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - HACKATOM.save(deps.storage, &msg)?; - Ok(Response::default()) -} - -fn execute( - deps: DepsMut, - env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - let init = HACKATOM.load(deps.storage)?; - let balance = deps.querier.query_all_balances(env.contract.address)?; - - let resp = Response::new().add_message(BankMsg::Send { - to_address: init.beneficiary, - amount: balance, - }); - - Ok(resp) -} - -fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { - match msg { - QueryMsg::Beneficiary {} => { - let res = HACKATOM.load(deps.storage)?; - to_binary(&res) - } - } -} - -fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { - HACKATOM.update::<_, StdError>(deps.storage, |mut state| { - state.beneficiary = msg.new_guy; - Ok(state) - })?; - let resp = Response::new().add_attribute("migrate", "successful"); - Ok(resp) -} - -pub fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_migrate(migrate); - Box::new(contract) -} - -#[allow(dead_code)] -pub fn custom_contract() -> Box> -where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, -{ - let contract = - ContractWrapper::new_with_empty(execute, instantiate, query).with_migrate_empty(migrate); - Box::new(contract) -} diff --git a/packages/multi-test/src/test_helpers/contracts/payout.rs b/packages/multi-test/src/test_helpers/contracts/payout.rs deleted file mode 100644 index 4e9f1c1b9..000000000 --- a/packages/multi-test/src/test_helpers/contracts/payout.rs +++ /dev/null @@ -1,90 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt; - -use cosmwasm_std::{ - to_binary, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdError, -}; -use cw_storage_plus::Item; - -use crate::contracts::{Contract, ContractWrapper}; -use crate::test_helpers::{EmptyMsg, COUNT}; - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct InstantiateMessage { - pub payout: Coin, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct SudoMsg { - pub set_count: u32, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum QueryMsg { - Count {}, - Payout {}, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct CountResponse { - pub count: u32, -} - -const PAYOUT: Item = Item::new("payout"); - -fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMessage, -) -> Result { - PAYOUT.save(deps.storage, &msg)?; - COUNT.save(deps.storage, &1)?; - Ok(Response::default()) -} - -fn execute( - deps: DepsMut, - _env: Env, - info: MessageInfo, - _msg: EmptyMsg, -) -> Result { - // always try to payout what was set originally - let payout = PAYOUT.load(deps.storage)?; - let msg = BankMsg::Send { - to_address: info.sender.into(), - amount: vec![payout.payout], - }; - Ok(Response::new() - .add_message(msg) - .add_attribute("action", "payout")) -} - -fn sudo(deps: DepsMut, _env: Env, msg: SudoMsg) -> Result { - COUNT.save(deps.storage, &msg.set_count)?; - Ok(Response::default()) -} - -fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { - match msg { - QueryMsg::Count {} => { - let count = COUNT.load(deps.storage)?; - let res = CountResponse { count }; - to_binary(&res) - } - QueryMsg::Payout {} => { - let payout = PAYOUT.load(deps.storage)?; - to_binary(&payout) - } - } -} - -pub fn contract() -> Box> -where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, -{ - let contract = - ContractWrapper::new_with_empty(execute, instantiate, query).with_sudo_empty(sudo); - Box::new(contract) -} diff --git a/packages/multi-test/src/test_helpers/contracts/reflect.rs b/packages/multi-test/src/test_helpers/contracts/reflect.rs deleted file mode 100644 index 11a107e8b..000000000 --- a/packages/multi-test/src/test_helpers/contracts/reflect.rs +++ /dev/null @@ -1,72 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, Event, MessageInfo, Reply, Response, StdError, SubMsg, -}; -use cw_storage_plus::Map; - -use crate::contracts::{Contract, ContractWrapper}; -use crate::test_helpers::contracts::payout; -use crate::test_helpers::{CustomMsg, EmptyMsg, COUNT}; - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct Message { - pub messages: Vec>, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum QueryMsg { - Count {}, - Reply { id: u64 }, -} - -const REFLECT: Map = Map::new("reflect"); - -fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: EmptyMsg, -) -> Result, StdError> { - COUNT.save(deps.storage, &0)?; - Ok(Response::default()) -} - -fn execute( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: Message, -) -> Result, StdError> { - COUNT.update::<_, StdError>(deps.storage, |old| Ok(old + 1))?; - - Ok(Response::new().add_submessages(msg.messages)) -} - -fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { - match msg { - QueryMsg::Count {} => { - let count = COUNT.load(deps.storage)?; - let res = payout::CountResponse { count }; - to_binary(&res) - } - QueryMsg::Reply { id } => { - let reply = REFLECT.load(deps.storage, id)?; - to_binary(&reply) - } - } -} - -fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result, StdError> { - REFLECT.save(deps.storage, msg.id, &msg)?; - // add custom event here to test - let event = Event::new("custom") - .add_attribute("from", "reply") - .add_attribute("to", "test"); - Ok(Response::new().add_event(event)) -} - -pub fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_reply(reply); - Box::new(contract) -} diff --git a/packages/multi-test/src/transactions.rs b/packages/multi-test/src/transactions.rs deleted file mode 100644 index 7b9c5b598..000000000 --- a/packages/multi-test/src/transactions.rs +++ /dev/null @@ -1,589 +0,0 @@ -#[cfg(feature = "iterator")] -use std::cmp::Ordering; -use std::collections::BTreeMap; -#[cfg(feature = "iterator")] -use std::iter; -#[cfg(feature = "iterator")] -use std::iter::Peekable; -#[cfg(feature = "iterator")] -use std::ops::{Bound, RangeBounds}; - -use cosmwasm_std::Storage; -#[cfg(feature = "iterator")] -use cosmwasm_std::{Order, Record}; - -use anyhow::Result as AnyResult; - -#[cfg(feature = "iterator")] -/// The BTreeMap specific key-value pair reference type, as returned by BTreeMap, T>::range. -/// This is internal as it can change any time if the map implementation is swapped out. -type BTreeMapPairRef<'a, T = Vec> = (&'a Vec, &'a T); - -pub fn transactional(base: &mut dyn Storage, action: F) -> AnyResult -where - F: FnOnce(&mut dyn Storage, &dyn Storage) -> AnyResult, -{ - let mut cache = StorageTransaction::new(base); - let res = action(&mut cache, base)?; - cache.prepare().commit(base); - Ok(res) -} - -pub struct StorageTransaction<'a> { - /// read-only access to backing storage - storage: &'a dyn Storage, - /// these are local changes not flushed to backing storage - local_state: BTreeMap, Delta>, - /// a log of local changes not yet flushed to backing storage - rep_log: RepLog, -} - -impl<'a> StorageTransaction<'a> { - pub fn new(storage: &'a dyn Storage) -> Self { - StorageTransaction { - storage, - local_state: BTreeMap::new(), - rep_log: RepLog::new(), - } - } - - /// prepares this transaction to be committed to storage - pub fn prepare(self) -> RepLog { - self.rep_log - } -} - -impl<'a> Storage for StorageTransaction<'a> { - fn get(&self, key: &[u8]) -> Option> { - match self.local_state.get(key) { - Some(val) => match val { - Delta::Set { value } => Some(value.clone()), - Delta::Delete {} => None, - }, - None => self.storage.get(key), - } - } - - fn set(&mut self, key: &[u8], value: &[u8]) { - let op = Op::Set { - key: key.to_vec(), - value: value.to_vec(), - }; - self.local_state.insert(key.to_vec(), op.to_delta()); - self.rep_log.append(op); - } - - fn remove(&mut self, key: &[u8]) { - let op = Op::Delete { key: key.to_vec() }; - self.local_state.insert(key.to_vec(), op.to_delta()); - self.rep_log.append(op); - } - - #[cfg(feature = "iterator")] - /// range allows iteration over a set of keys, either forwards or backwards - /// uses standard rust range notation, and eg db.range(b"foo"..b"bar") also works reverse - fn range<'b>( - &'b self, - start: Option<&[u8]>, - end: Option<&[u8]>, - order: Order, - ) -> Box + 'b> { - let bounds = range_bounds(start, end); - - // BTreeMap.range panics if range is start > end. - // However, this cases represent just empty range and we treat it as such. - let local: Box>> = - match (bounds.start_bound(), bounds.end_bound()) { - (Bound::Included(start), Bound::Excluded(end)) if start > end => { - Box::new(iter::empty()) - } - _ => { - let local_raw = self.local_state.range(bounds); - match order { - Order::Ascending => Box::new(local_raw), - Order::Descending => Box::new(local_raw.rev()), - } - } - }; - - let base = self.storage.range(start, end, order); - let merged = MergeOverlay::new(local, base, order); - Box::new(merged) - } -} - -pub struct RepLog { - /// this is a list of changes to be written to backing storage upon commit - ops_log: Vec, -} - -impl RepLog { - fn new() -> Self { - RepLog { ops_log: vec![] } - } - - /// appends an op to the list of changes to be applied upon commit - fn append(&mut self, op: Op) { - self.ops_log.push(op); - } - - /// applies the stored list of `Op`s to the provided `Storage` - pub fn commit(self, storage: &mut dyn Storage) { - for op in self.ops_log { - op.apply(storage); - } - } -} - -/// Op is the user operation, which can be stored in the RepLog. -/// Currently Set or Delete. -enum Op { - /// represents the `Set` operation for setting a key-value pair in storage - Set { - key: Vec, - value: Vec, - }, - Delete { - key: Vec, - }, -} - -impl Op { - /// applies this `Op` to the provided storage - pub fn apply(&self, storage: &mut dyn Storage) { - match self { - Op::Set { key, value } => storage.set(key, value), - Op::Delete { key } => storage.remove(key), - } - } - - /// converts the Op to a delta, which can be stored in a local cache - pub fn to_delta(&self) -> Delta { - match self { - Op::Set { value, .. } => Delta::Set { - value: value.clone(), - }, - Op::Delete { .. } => Delta::Delete {}, - } - } -} - -/// Delta is the changes, stored in the local transaction cache. -/// This is either Set{value} or Delete{}. Note that this is the "value" -/// part of a BTree, so the Key (from the Op) is stored separately. -enum Delta { - Set { value: Vec }, - Delete {}, -} - -#[cfg(feature = "iterator")] -struct MergeOverlay<'a, L, R> -where - L: Iterator>, - R: Iterator, -{ - left: Peekable, - right: Peekable, - order: Order, -} - -#[cfg(feature = "iterator")] -impl<'a, L, R> MergeOverlay<'a, L, R> -where - L: Iterator>, - R: Iterator, -{ - fn new(left: L, right: R, order: Order) -> Self { - MergeOverlay { - left: left.peekable(), - right: right.peekable(), - order, - } - } - - fn pick_match(&mut self, lkey: Vec, rkey: Vec) -> Option { - // compare keys - result is such that Ordering::Less => return left side - let order = match self.order { - Order::Ascending => lkey.cmp(&rkey), - Order::Descending => rkey.cmp(&lkey), - }; - - // left must be translated and filtered before return, not so with right - match order { - Ordering::Less => self.take_left(), - Ordering::Equal => { - // - let _ = self.right.next(); - self.take_left() - } - Ordering::Greater => self.right.next(), - } - } - - /// take_left must only be called when we know self.left.next() will return Some - fn take_left(&mut self) -> Option { - let (lkey, lval) = self.left.next().unwrap(); - match lval { - Delta::Set { value } => Some((lkey.clone(), value.clone())), - Delta::Delete {} => self.next(), - } - } -} - -#[cfg(feature = "iterator")] -impl<'a, L, R> Iterator for MergeOverlay<'a, L, R> -where - L: Iterator>, - R: Iterator, -{ - type Item = Record; - - fn next(&mut self) -> Option { - let (left, right) = (self.left.peek(), self.right.peek()); - match (left, right) { - (Some(litem), Some(ritem)) => { - let (lkey, _) = litem; - let (rkey, _) = ritem; - - // we just use cloned keys to avoid double mutable references - // (we must release the return value from peek, before beginning to call next or other mut methods - let (l, r) = (lkey.to_vec(), rkey.to_vec()); - self.pick_match(l, r) - } - (Some(_), None) => self.take_left(), - (None, Some(_)) => self.right.next(), - (None, None) => None, - } - } -} - -#[cfg(feature = "iterator")] -fn range_bounds(start: Option<&[u8]>, end: Option<&[u8]>) -> impl RangeBounds> { - ( - start.map_or(Bound::Unbounded, |x| Bound::Included(x.to_vec())), - end.map_or(Bound::Unbounded, |x| Bound::Excluded(x.to_vec())), - ) -} - -#[cfg(test)] -mod test { - use super::*; - use std::cell::RefCell; - use std::ops::{Deref, DerefMut}; - - use cosmwasm_std::MemoryStorage; - - #[test] - fn wrap_storage() { - let mut store = MemoryStorage::new(); - let mut wrap = StorageTransaction::new(&store); - wrap.set(b"foo", b"bar"); - - assert_eq!(None, store.get(b"foo")); - wrap.prepare().commit(&mut store); - assert_eq!(Some(b"bar".to_vec()), store.get(b"foo")); - } - - #[test] - fn wrap_ref_cell() { - let store = RefCell::new(MemoryStorage::new()); - let ops = { - let refer = store.borrow(); - let mut wrap = StorageTransaction::new(refer.deref()); - wrap.set(b"foo", b"bar"); - assert_eq!(None, store.borrow().get(b"foo")); - wrap.prepare() - }; - ops.commit(store.borrow_mut().deref_mut()); - assert_eq!(Some(b"bar".to_vec()), store.borrow().get(b"foo")); - } - - #[test] - fn wrap_box_storage() { - let mut store: Box = Box::new(MemoryStorage::new()); - let mut wrap = StorageTransaction::new(store.as_ref()); - wrap.set(b"foo", b"bar"); - - assert_eq!(None, store.get(b"foo")); - wrap.prepare().commit(store.as_mut()); - assert_eq!(Some(b"bar".to_vec()), store.get(b"foo")); - } - - #[test] - fn wrap_box_dyn_storage() { - let mut store: Box = Box::new(MemoryStorage::new()); - let mut wrap = StorageTransaction::new(store.as_ref()); - wrap.set(b"foo", b"bar"); - - assert_eq!(None, store.get(b"foo")); - wrap.prepare().commit(store.as_mut()); - assert_eq!(Some(b"bar".to_vec()), store.get(b"foo")); - } - - #[test] - fn wrap_ref_cell_dyn_storage() { - let inner: Box = Box::new(MemoryStorage::new()); - let store = RefCell::new(inner); - // Tricky but working - // 1. we cannot inline StorageTransaction::new(store.borrow().as_ref()) as Ref must outlive StorageTransaction - // 2. we cannot call ops.commit() until refer is out of scope - borrow_mut() and borrow() on the same object - // This can work with some careful scoping, this provides a good reference - let ops = { - let refer = store.borrow(); - let mut wrap = StorageTransaction::new(refer.as_ref()); - wrap.set(b"foo", b"bar"); - - assert_eq!(None, store.borrow().get(b"foo")); - wrap.prepare() - }; - ops.commit(store.borrow_mut().as_mut()); - assert_eq!(Some(b"bar".to_vec()), store.borrow().get(b"foo")); - } - - #[cfg(feature = "iterator")] - // iterator_test_suite takes a storage, adds data and runs iterator tests - // the storage must previously have exactly one key: "foo" = "bar" - // (this allows us to test StorageTransaction and other wrapped storage better) - fn iterator_test_suite(store: &mut S) { - // ensure we had previously set "foo" = "bar" - assert_eq!(store.get(b"foo"), Some(b"bar".to_vec())); - assert_eq!(store.range(None, None, Order::Ascending).count(), 1); - - // setup - add some data, and delete part of it as well - store.set(b"ant", b"hill"); - store.set(b"ze", b"bra"); - - // noise that should be ignored - store.set(b"bye", b"bye"); - store.remove(b"bye"); - - // unbounded - { - let iter = store.range(None, None, Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"ant".to_vec(), b"hill".to_vec()), - (b"foo".to_vec(), b"bar".to_vec()), - (b"ze".to_vec(), b"bra".to_vec()), - ] - ); - } - - // unbounded (descending) - { - let iter = store.range(None, None, Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"ze".to_vec(), b"bra".to_vec()), - (b"foo".to_vec(), b"bar".to_vec()), - (b"ant".to_vec(), b"hill".to_vec()), - ] - ); - } - - // bounded - { - let iter = store.range(Some(b"f"), Some(b"n"), Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![(b"foo".to_vec(), b"bar".to_vec())]); - } - - // bounded (descending) - { - let iter = store.range(Some(b"air"), Some(b"loop"), Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"foo".to_vec(), b"bar".to_vec()), - (b"ant".to_vec(), b"hill".to_vec()), - ] - ); - } - - // bounded empty [a, a) - { - let iter = store.range(Some(b"foo"), Some(b"foo"), Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![]); - } - - // bounded empty [a, a) (descending) - { - let iter = store.range(Some(b"foo"), Some(b"foo"), Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![]); - } - - // bounded empty [a, b) with b < a - { - let iter = store.range(Some(b"z"), Some(b"a"), Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![]); - } - - // bounded empty [a, b) with b < a (descending) - { - let iter = store.range(Some(b"z"), Some(b"a"), Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![]); - } - - // right unbounded - { - let iter = store.range(Some(b"f"), None, Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"foo".to_vec(), b"bar".to_vec()), - (b"ze".to_vec(), b"bra".to_vec()), - ] - ); - } - - // right unbounded (descending) - { - let iter = store.range(Some(b"f"), None, Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"ze".to_vec(), b"bra".to_vec()), - (b"foo".to_vec(), b"bar".to_vec()), - ] - ); - } - - // left unbounded - { - let iter = store.range(None, Some(b"f"), Order::Ascending); - let elements: Vec = iter.collect(); - assert_eq!(elements, vec![(b"ant".to_vec(), b"hill".to_vec()),]); - } - - // left unbounded (descending) - { - let iter = store.range(None, Some(b"no"), Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"foo".to_vec(), b"bar".to_vec()), - (b"ant".to_vec(), b"hill".to_vec()), - ] - ); - } - } - - #[test] - fn delete_local() { - let mut base = Box::new(MemoryStorage::new()); - let mut check = StorageTransaction::new(base.as_ref()); - check.set(b"foo", b"bar"); - check.set(b"food", b"bank"); - check.remove(b"foo"); - - assert_eq!(check.get(b"foo"), None); - assert_eq!(check.get(b"food"), Some(b"bank".to_vec())); - - // now commit to base and query there - check.prepare().commit(base.as_mut()); - assert_eq!(base.get(b"foo"), None); - assert_eq!(base.get(b"food"), Some(b"bank".to_vec())); - } - - #[test] - fn delete_from_base() { - let mut base = Box::new(MemoryStorage::new()); - base.set(b"foo", b"bar"); - let mut check = StorageTransaction::new(base.as_ref()); - check.set(b"food", b"bank"); - check.remove(b"foo"); - - assert_eq!(check.get(b"foo"), None); - assert_eq!(check.get(b"food"), Some(b"bank".to_vec())); - - // now commit to base and query there - check.prepare().commit(base.as_mut()); - assert_eq!(base.get(b"foo"), None); - assert_eq!(base.get(b"food"), Some(b"bank".to_vec())); - } - - #[test] - #[cfg(feature = "iterator")] - fn storage_transaction_iterator_empty_base() { - let base = MemoryStorage::new(); - let mut check = StorageTransaction::new(&base); - check.set(b"foo", b"bar"); - iterator_test_suite(&mut check); - } - - #[test] - #[cfg(feature = "iterator")] - fn storage_transaction_iterator_with_base_data() { - let mut base = MemoryStorage::new(); - base.set(b"foo", b"bar"); - let mut check = StorageTransaction::new(&base); - iterator_test_suite(&mut check); - } - - #[test] - #[cfg(feature = "iterator")] - fn storage_transaction_iterator_removed_items_from_base() { - let mut base = Box::new(MemoryStorage::new()); - base.set(b"foo", b"bar"); - base.set(b"food", b"bank"); - let mut check = StorageTransaction::new(base.as_ref()); - check.remove(b"food"); - iterator_test_suite(&mut check); - } - - #[test] - fn commit_writes_through() { - let mut base = Box::new(MemoryStorage::new()); - base.set(b"foo", b"bar"); - - let mut check = StorageTransaction::new(base.as_ref()); - assert_eq!(check.get(b"foo"), Some(b"bar".to_vec())); - check.set(b"subtx", b"works"); - check.prepare().commit(base.as_mut()); - - assert_eq!(base.get(b"subtx"), Some(b"works".to_vec())); - } - - #[test] - fn storage_remains_readable() { - let mut base = MemoryStorage::new(); - base.set(b"foo", b"bar"); - - let mut stxn1 = StorageTransaction::new(&base); - - assert_eq!(stxn1.get(b"foo"), Some(b"bar".to_vec())); - - stxn1.set(b"subtx", b"works"); - assert_eq!(stxn1.get(b"subtx"), Some(b"works".to_vec())); - - // Can still read from base, txn is not yet committed - assert_eq!(base.get(b"subtx"), None); - - stxn1.prepare().commit(&mut base); - assert_eq!(base.get(b"subtx"), Some(b"works".to_vec())); - } - - #[test] - fn ignore_same_as_rollback() { - let mut base = MemoryStorage::new(); - base.set(b"foo", b"bar"); - - let mut check = StorageTransaction::new(&base); - assert_eq!(check.get(b"foo"), Some(b"bar".to_vec())); - check.set(b"subtx", b"works"); - - assert_eq!(base.get(b"subtx"), None); - } -} diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs deleted file mode 100644 index bb0490332..000000000 --- a/packages/multi-test/src/wasm.rs +++ /dev/null @@ -1,1522 +0,0 @@ -use std::collections::HashMap; -use std::fmt; -use std::ops::Deref; - -use cosmwasm_std::{ - to_binary, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, - ContractInfoResponse, CustomQuery, Deps, DepsMut, Env, Event, MessageInfo, Order, Querier, - QuerierWrapper, Record, Reply, ReplyOn, Response, StdResult, Storage, SubMsg, SubMsgResponse, - SubMsgResult, TransactionInfo, WasmMsg, WasmQuery, -}; -use prost::Message; -use schemars::JsonSchema; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; - -use cw_storage_plus::Map; - -use crate::app::{CosmosRouter, RouterQuerier}; -use crate::contracts::Contract; -use crate::error::Error; -use crate::executor::AppResponse; -use crate::prefixed_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; -use crate::transactions::transactional; -use cosmwasm_std::testing::mock_wasmd_attr; - -use anyhow::{bail, Context, Result as AnyResult}; - -// Contract state is kept in Storage, separate from the contracts themselves -const CONTRACTS: Map<&Addr, ContractData> = Map::new("contracts"); - -pub const NAMESPACE_WASM: &[u8] = b"wasm"; -const CONTRACT_ATTR: &str = "_contract_addr"; - -#[derive(Clone, std::fmt::Debug, PartialEq, Eq, JsonSchema)] -pub struct WasmSudo { - pub contract_addr: Addr, - pub msg: Binary, -} - -impl WasmSudo { - pub fn new(contract_addr: &Addr, msg: &T) -> StdResult { - Ok(WasmSudo { - contract_addr: contract_addr.clone(), - msg: to_binary(msg)?, - }) - } -} - -/// Contract Data includes information about contract, equivalent of `ContractInfo` in wasmd -/// interface. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct ContractData { - /// Identifier of stored contract code - pub code_id: usize, - /// Address of account who initially instantiated the contract - pub creator: Addr, - /// Optional address of account who can execute migrations - pub admin: Option, - /// Metadata passed while contract instantiation - pub label: String, - /// Blockchain height in the moment of instantiating the contract - pub created: u64, -} - -pub trait Wasm { - /// Handles all WasmQuery requests - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - request: WasmQuery, - ) -> AnyResult; - - /// Handles all WasmMsg messages - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - msg: WasmMsg, - ) -> AnyResult; - - /// Admin interface, cannot be called via CosmosMsg - fn sudo( - &self, - api: &dyn Api, - contract_addr: Addr, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: Binary, - ) -> AnyResult; -} - -pub struct WasmKeeper { - /// code is in-memory lookup that stands in for wasm code - /// this can only be edited on the WasmRouter, and just read in caches - codes: HashMap>>, - /// Just markers to make type elision fork when using it as `Wasm` trait - _p: std::marker::PhantomData, -} - -impl Default for WasmKeeper { - fn default() -> Self { - Self { - codes: HashMap::default(), - _p: std::marker::PhantomData, - } - } -} - -impl Wasm for WasmKeeper -where - ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, -{ - fn query( - &self, - api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - request: WasmQuery, - ) -> AnyResult { - match request { - WasmQuery::Smart { contract_addr, msg } => { - let addr = api.addr_validate(&contract_addr)?; - self.query_smart(addr, api, storage, querier, block, msg.into()) - } - WasmQuery::Raw { contract_addr, key } => { - let addr = api.addr_validate(&contract_addr)?; - Ok(self.query_raw(addr, storage, &key)) - } - WasmQuery::ContractInfo { contract_addr } => { - let addr = api.addr_validate(&contract_addr)?; - let contract = self.load_contract(storage, &addr)?; - let mut res = ContractInfoResponse::new(contract.code_id as u64, contract.creator); - res.admin = contract.admin.map(|x| x.into()); - to_binary(&res).map_err(Into::into) - } - query => bail!(Error::UnsupportedWasmQuery(query)), - } - } - - fn execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - msg: WasmMsg, - ) -> AnyResult { - self.execute_wasm(api, storage, router, block, sender.clone(), msg.clone()) - .context(format!( - "error executing WasmMsg:\nsender: {}\n{:?}", - sender, msg - )) - } - - fn sudo( - &self, - api: &dyn Api, - contract: Addr, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: Binary, - ) -> AnyResult { - let custom_event = Event::new("sudo").add_attribute(CONTRACT_ATTR, &contract); - - let res = self.call_sudo(contract.clone(), api, storage, router, block, msg.to_vec())?; - let (res, msgs) = self.build_app_response(&contract, custom_event, res); - self.process_response(api, router, storage, block, contract, res, msgs) - } -} - -impl WasmKeeper { - pub fn store_code(&mut self, code: Box>) -> usize { - let idx = self.codes.len() + 1; - self.codes.insert(idx, code); - idx - } - - pub fn load_contract(&self, storage: &dyn Storage, address: &Addr) -> AnyResult { - CONTRACTS - .load(&prefixed_read(storage, NAMESPACE_WASM), address) - .map_err(Into::into) - } - - pub fn dump_wasm_raw(&self, storage: &dyn Storage, address: &Addr) -> Vec { - let storage = self.contract_storage_readonly(storage, address); - storage.range(None, None, Order::Ascending).collect() - } - - fn contract_namespace(&self, contract: &Addr) -> Vec { - let mut name = b"contract_data/".to_vec(); - name.extend_from_slice(contract.as_bytes()); - name - } - - fn contract_storage<'a>( - &self, - storage: &'a mut dyn Storage, - address: &Addr, - ) -> Box { - // We double-namespace this, once from global storage -> wasm_storage - // then from wasm_storage -> the contracts subspace - let namespace = self.contract_namespace(address); - let storage = PrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); - Box::new(storage) - } - - // fails RUNTIME if you try to write. please don't - fn contract_storage_readonly<'a>( - &self, - storage: &'a dyn Storage, - address: &Addr, - ) -> Box { - // We double-namespace this, once from global storage -> wasm_storage - // then from wasm_storage -> the contracts subspace - let namespace = self.contract_namespace(address); - let storage = ReadonlyPrefixedStorage::multilevel(storage, &[NAMESPACE_WASM, &namespace]); - Box::new(storage) - } - - fn verify_attributes(attributes: &[Attribute]) -> AnyResult<()> { - for attr in attributes { - let key = attr.key.trim(); - let val = attr.value.trim(); - - if key.is_empty() { - bail!(Error::empty_attribute_key(val)); - } - - if val.is_empty() { - bail!(Error::empty_attribute_value(key)); - } - - if key.starts_with('_') { - bail!(Error::reserved_attribute_key(key)); - } - } - - Ok(()) - } - - fn verify_response(response: Response) -> AnyResult> - where - T: Clone + fmt::Debug + PartialEq + JsonSchema, - { - Self::verify_attributes(&response.attributes)?; - - for event in &response.events { - Self::verify_attributes(&event.attributes)?; - let ty = event.ty.trim(); - if ty.len() < 2 { - bail!(Error::event_type_too_short(ty)); - } - } - - Ok(response) - } -} - -impl WasmKeeper -where - ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, -{ - pub fn new() -> Self { - Self::default() - } - - pub fn query_smart( - &self, - address: Addr, - api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - msg: Vec, - ) -> AnyResult { - self.with_storage_readonly( - api, - storage, - querier, - block, - address, - |handler, deps, env| handler.query(deps, env, msg), - ) - } - - pub fn query_raw(&self, address: Addr, storage: &dyn Storage, key: &[u8]) -> Binary { - let storage = self.contract_storage_readonly(storage, &address); - let data = storage.get(key).unwrap_or_default(); - data.into() - } - - fn send( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: T, - recipient: String, - amount: &[Coin], - ) -> AnyResult - where - T: Into, - { - if !amount.is_empty() { - let msg: cosmwasm_std::CosmosMsg = BankMsg::Send { - to_address: recipient, - amount: amount.to_vec(), - } - .into(); - let res = router.execute(api, storage, block, sender.into(), msg)?; - Ok(res) - } else { - Ok(AppResponse::default()) - } - } - - /// unified logic for UpdateAdmin and ClearAdmin messages - fn update_admin( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - sender: Addr, - contract_addr: &str, - new_admin: Option, - ) -> AnyResult { - let contract_addr = api.addr_validate(contract_addr)?; - let admin = new_admin.map(|a| api.addr_validate(&a)).transpose()?; - - // check admin status - let mut data = self.load_contract(storage, &contract_addr)?; - if data.admin != Some(sender) { - bail!("Only admin can update the contract admin: {:?}", data.admin); - } - // update admin field - data.admin = admin; - self.save_contract(storage, &contract_addr, &data)?; - - // no custom event here - Ok(AppResponse { - data: None, - events: vec![], - }) - } - - // this returns the contract address as well, so we can properly resend the data - fn execute_wasm( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - sender: Addr, - wasm_msg: WasmMsg, - ) -> AnyResult { - match wasm_msg { - WasmMsg::Execute { - contract_addr, - msg, - funds, - } => { - let contract_addr = api.addr_validate(&contract_addr)?; - // first move the cash - self.send( - api, - storage, - router, - block, - sender.clone(), - contract_addr.clone().into(), - &funds, - )?; - - // then call the contract - let info = MessageInfo { sender, funds }; - let res = self.call_execute( - api, - storage, - contract_addr.clone(), - router, - block, - info, - msg.to_vec(), - )?; - - let custom_event = - Event::new("execute").add_attribute(CONTRACT_ATTR, &contract_addr); - - let (res, msgs) = self.build_app_response(&contract_addr, custom_event, res); - let mut res = - self.process_response(api, router, storage, block, contract_addr, res, msgs)?; - res.data = execute_response(res.data); - Ok(res) - } - WasmMsg::Instantiate { - admin, - code_id, - msg, - funds, - label, - } => { - if label.is_empty() { - bail!("Label is required on all contracts"); - } - - let contract_addr = self.register_contract( - storage, - code_id as usize, - sender.clone(), - admin.map(Addr::unchecked), - label, - block.height, - )?; - - // move the cash - self.send( - api, - storage, - router, - block, - sender.clone(), - contract_addr.clone().into(), - &funds, - )?; - - // then call the contract - let info = MessageInfo { sender, funds }; - let res = self.call_instantiate( - contract_addr.clone(), - api, - storage, - router, - block, - info, - msg.to_vec(), - )?; - - let custom_event = Event::new("instantiate") - .add_attribute(CONTRACT_ATTR, &contract_addr) - .add_attribute("code_id", code_id.to_string()); - - let (res, msgs) = self.build_app_response(&contract_addr, custom_event, res); - let mut res = self.process_response( - api, - router, - storage, - block, - contract_addr.clone(), - res, - msgs, - )?; - res.data = Some(instantiate_response(res.data, &contract_addr)); - Ok(res) - } - WasmMsg::Migrate { - contract_addr, - new_code_id, - msg, - } => { - let contract_addr = api.addr_validate(&contract_addr)?; - - // check admin status and update the stored code_id - let new_code_id = new_code_id as usize; - if !self.codes.contains_key(&new_code_id) { - bail!("Cannot migrate contract to unregistered code id"); - } - let mut data = self.load_contract(storage, &contract_addr)?; - if data.admin != Some(sender) { - bail!("Only admin can migrate contract: {:?}", data.admin); - } - data.code_id = new_code_id; - self.save_contract(storage, &contract_addr, &data)?; - - // then call migrate - let res = self.call_migrate( - contract_addr.clone(), - api, - storage, - router, - block, - msg.to_vec(), - )?; - - let custom_event = Event::new("migrate") - .add_attribute(CONTRACT_ATTR, &contract_addr) - .add_attribute("code_id", new_code_id.to_string()); - let (res, msgs) = self.build_app_response(&contract_addr, custom_event, res); - let mut res = - self.process_response(api, router, storage, block, contract_addr, res, msgs)?; - res.data = execute_response(res.data); - Ok(res) - } - WasmMsg::UpdateAdmin { - contract_addr, - admin, - } => self.update_admin(api, storage, sender, &contract_addr, Some(admin)), - WasmMsg::ClearAdmin { contract_addr } => { - self.update_admin(api, storage, sender, &contract_addr, None) - } - msg => bail!(Error::UnsupportedWasmMsg(msg)), - } - } - - /// This will execute the given messages, making all changes to the local cache. - /// This *will* write some data to the cache if the message fails half-way through. - /// All sequential calls to RouterCache will be one atomic unit (all commit or all fail). - /// - /// For normal use cases, you can use Router::execute() or Router::execute_multi(). - /// This is designed to be handled internally as part of larger process flows. - /// - /// The `data` on `AppResponse` is data returned from `reply` call, not from execution of - /// submessage itself. In case if `reply` is not called, no `data` is set. - fn execute_submsg( - &self, - api: &dyn Api, - router: &dyn CosmosRouter, - storage: &mut dyn Storage, - block: &BlockInfo, - contract: Addr, - msg: SubMsg, - ) -> AnyResult { - let SubMsg { - msg, id, reply_on, .. - } = msg; - - // execute in cache - let res = transactional(storage, |write_cache, _| { - router.execute(api, write_cache, block, contract.clone(), msg) - }); - - // call reply if meaningful - if let Ok(mut r) = res { - if matches!(reply_on, ReplyOn::Always | ReplyOn::Success) { - let reply = Reply { - id, - result: SubMsgResult::Ok(SubMsgResponse { - events: r.events.clone(), - data: r.data, - }), - }; - // do reply and combine it with the original response - let reply_res = self._reply(api, router, storage, block, contract, reply)?; - // override data - r.data = reply_res.data; - // append the events - r.events.extend_from_slice(&reply_res.events); - } else { - // reply is not called, no data should be rerturned - r.data = None; - } - - Ok(r) - } else if let Err(e) = res { - if matches!(reply_on, ReplyOn::Always | ReplyOn::Error) { - let reply = Reply { - id, - result: SubMsgResult::Err(e.to_string()), - }; - self._reply(api, router, storage, block, contract, reply) - } else { - Err(e) - } - } else { - res - } - } - - fn _reply( - &self, - api: &dyn Api, - router: &dyn CosmosRouter, - storage: &mut dyn Storage, - block: &BlockInfo, - contract: Addr, - reply: Reply, - ) -> AnyResult { - let ok_attr = if reply.result.is_ok() { - "handle_success" - } else { - "handle_failure" - }; - let custom_event = Event::new("reply") - .add_attribute(CONTRACT_ATTR, &contract) - .add_attribute("mode", ok_attr); - - let res = self.call_reply(contract.clone(), api, storage, router, block, reply)?; - let (res, msgs) = self.build_app_response(&contract, custom_event, res); - self.process_response(api, router, storage, block, contract, res, msgs) - } - - // this captures all the events and data from the contract call. - // it does not handle the messages - fn build_app_response( - &self, - contract: &Addr, - custom_event: Event, // entry-point specific custom event added by x/wasm - response: Response, - ) -> (AppResponse, Vec>) { - let Response { - messages, - attributes, - events, - data, - .. - } = response; - - // always add custom event - let mut app_events = Vec::with_capacity(2 + events.len()); - app_events.push(custom_event); - - // we only emit the `wasm` event if some attributes are specified - if !attributes.is_empty() { - // turn attributes into event and place it first - let wasm_event = Event::new("wasm") - .add_attribute(CONTRACT_ATTR, contract) - .add_attributes(attributes); - app_events.push(wasm_event); - } - - // These need to get `wasm-` prefix to match the wasmd semantics (custom wasm messages cannot - // fake system level event types, like transfer from the bank module) - let wasm_events = events.into_iter().map(|mut ev| { - ev.ty = format!("wasm-{}", ev.ty); - ev.attributes - .insert(0, mock_wasmd_attr(CONTRACT_ATTR, contract)); - ev - }); - app_events.extend(wasm_events); - - let app = AppResponse { - events: app_events, - data, - }; - (app, messages) - } - - fn process_response( - &self, - api: &dyn Api, - router: &dyn CosmosRouter, - storage: &mut dyn Storage, - block: &BlockInfo, - contract: Addr, - response: AppResponse, - messages: Vec>, - ) -> AnyResult { - let AppResponse { mut events, data } = response; - - // recurse in all messages - let data = messages.into_iter().try_fold(data, |data, resend| { - let subres = - self.execute_submsg(api, router, storage, block, contract.clone(), resend)?; - events.extend_from_slice(&subres.events); - Ok::<_, anyhow::Error>(subres.data.or(data)) - })?; - - Ok(AppResponse { events, data }) - } - - /// This just creates an address and empty storage instance, returning the new address - /// You must call init after this to set up the contract properly. - /// These are separated into two steps to have cleaner return values. - pub fn register_contract( - &self, - storage: &mut dyn Storage, - code_id: usize, - creator: Addr, - admin: impl Into>, - label: String, - created: u64, - ) -> AnyResult { - if !self.codes.contains_key(&code_id) { - bail!("Cannot init contract with unregistered code id"); - } - - let addr = self.next_address(&prefixed_read(storage, NAMESPACE_WASM)); - - let info = ContractData { - code_id, - creator, - admin: admin.into(), - label, - created, - }; - self.save_contract(storage, &addr, &info)?; - Ok(addr) - } - - pub fn call_execute( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - address: Addr, - router: &dyn CosmosRouter, - block: &BlockInfo, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - Self::verify_response(self.with_storage( - api, - storage, - router, - block, - address, - |contract, deps, env| contract.execute(deps, env, info, msg), - )?) - } - - pub fn call_instantiate( - &self, - address: Addr, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - info: MessageInfo, - msg: Vec, - ) -> AnyResult> { - Self::verify_response(self.with_storage( - api, - storage, - router, - block, - address, - |contract, deps, env| contract.instantiate(deps, env, info, msg), - )?) - } - - pub fn call_reply( - &self, - address: Addr, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - reply: Reply, - ) -> AnyResult> { - Self::verify_response(self.with_storage( - api, - storage, - router, - block, - address, - |contract, deps, env| contract.reply(deps, env, reply), - )?) - } - - pub fn call_sudo( - &self, - address: Addr, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: Vec, - ) -> AnyResult> { - Self::verify_response(self.with_storage( - api, - storage, - router, - block, - address, - |contract, deps, env| contract.sudo(deps, env, msg), - )?) - } - - pub fn call_migrate( - &self, - address: Addr, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - msg: Vec, - ) -> AnyResult> { - Self::verify_response(self.with_storage( - api, - storage, - router, - block, - address, - |contract, deps, env| contract.migrate(deps, env, msg), - )?) - } - - fn get_env>(&self, address: T, block: &BlockInfo) -> Env { - Env { - block: block.clone(), - contract: ContractInfo { - address: address.into(), - }, - transaction: Some(TransactionInfo { index: 0 }), - } - } - - fn with_storage_readonly( - &self, - api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - block: &BlockInfo, - address: Addr, - action: F, - ) -> AnyResult - where - F: FnOnce(&Box>, Deps, Env) -> AnyResult, - { - let contract = self.load_contract(storage, &address)?; - let handler = self - .codes - .get(&contract.code_id) - .ok_or(Error::UnregisteredCodeId(contract.code_id))?; - let storage = self.contract_storage_readonly(storage, &address); - let env = self.get_env(address, block); - - let deps = Deps { - storage: storage.as_ref(), - api: api.deref(), - querier: QuerierWrapper::new(querier), - }; - action(handler, deps, env) - } - - fn with_storage( - &self, - api: &dyn Api, - storage: &mut dyn Storage, - router: &dyn CosmosRouter, - block: &BlockInfo, - address: Addr, - action: F, - ) -> AnyResult - where - F: FnOnce(&Box>, DepsMut, Env) -> AnyResult, - ExecC: DeserializeOwned, - { - let contract = self.load_contract(storage, &address)?; - let handler = self - .codes - .get(&contract.code_id) - .ok_or(Error::UnregisteredCodeId(contract.code_id))?; - - // We don't actually need a transaction here, as it is already embedded in a transactional. - // execute_submsg or App.execute_multi. - // However, we need to get write and read access to the same storage in two different objects, - // and this is the only way I know how to do so. - transactional(storage, |write_cache, read_store| { - let mut contract_storage = self.contract_storage(write_cache, &address); - let querier = RouterQuerier::new(router, api, read_store, block); - let env = self.get_env(address, block); - - let deps = DepsMut { - storage: contract_storage.as_mut(), - api: api.deref(), - querier: QuerierWrapper::new(&querier), - }; - action(handler, deps, env) - }) - } - - pub fn save_contract( - &self, - storage: &mut dyn Storage, - address: &Addr, - contract: &ContractData, - ) -> AnyResult<()> { - CONTRACTS - .save(&mut prefixed(storage, NAMESPACE_WASM), address, contract) - .map_err(Into::into) - } - - // FIXME: better addr generation - fn next_address(&self, storage: &dyn Storage) -> Addr { - // FIXME: quite inefficient if we actually had 100s of contracts - let count = CONTRACTS - .range_raw(storage, None, None, Order::Ascending) - .count(); - // we make this longer so it is not rejected by tests - // it is lowercase to be compatible with the MockApi implementation of cosmwasm-std >= 1.0.0-beta8 - Addr::unchecked(format!("contract{}", count)) - } -} - -// TODO: replace with code in utils - -#[derive(Clone, PartialEq, Message)] -struct InstantiateResponse { - #[prost(string, tag = "1")] - pub address: ::prost::alloc::string::String, - #[prost(bytes, tag = "2")] - pub data: ::prost::alloc::vec::Vec, -} - -// TODO: encode helpers in utils -fn instantiate_response(data: Option, contact_address: &Addr) -> Binary { - let data = data.unwrap_or_default().to_vec(); - let init_data = InstantiateResponse { - address: contact_address.into(), - data, - }; - let mut new_data = Vec::::with_capacity(init_data.encoded_len()); - // the data must encode successfully - init_data.encode(&mut new_data).unwrap(); - new_data.into() -} - -#[derive(Clone, PartialEq, Message)] -struct ExecuteResponse { - #[prost(bytes, tag = "1")] - pub data: ::prost::alloc::vec::Vec, -} - -// empty return if no data present in original -fn execute_response(data: Option) -> Option { - data.map(|d| { - let exec_data = ExecuteResponse { data: d.to_vec() }; - let mut new_data = Vec::::with_capacity(exec_data.encoded_len()); - // the data must encode successfully - exec_data.encode(&mut new_data).unwrap(); - new_data.into() - }) -} - -#[cfg(test)] -mod test { - use cosmwasm_std::testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}; - use cosmwasm_std::{coin, from_slice, to_vec, BankMsg, Coin, CosmosMsg, Empty, StdError}; - - use crate::app::Router; - use crate::bank::BankKeeper; - use crate::module::FailingModule; - use crate::staking::{DistributionKeeper, StakeKeeper}; - use crate::test_helpers::contracts::{caller, error, payout}; - use crate::test_helpers::EmptyMsg; - use crate::transactions::StorageTransaction; - - use super::*; - - /// Type alias for default build `Router` to make its reference in typical scenario - type BasicRouter = Router< - BankKeeper, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - >; - - fn mock_router() -> BasicRouter { - Router { - wasm: WasmKeeper::new(), - bank: BankKeeper::new(), - custom: FailingModule::new(), - staking: StakeKeeper::new(), - distribution: DistributionKeeper::new(), - } - } - - #[test] - fn register_contract() { - let api = MockApi::default(); - let mut wasm_storage = MockStorage::new(); - let mut keeper = WasmKeeper::new(); - let block = mock_env().block; - let code_id = keeper.store_code(error::contract(false)); - - transactional(&mut wasm_storage, |cache, _| { - // cannot register contract with unregistered codeId - keeper.register_contract( - cache, - code_id + 1, - Addr::unchecked("foobar"), - Addr::unchecked("admin"), - "label".to_owned(), - 1000, - ) - }) - .unwrap_err(); - - let contract_addr = transactional(&mut wasm_storage, |cache, _| { - // we can register a new instance of this code - keeper.register_contract( - cache, - code_id, - Addr::unchecked("foobar"), - Addr::unchecked("admin"), - "label".to_owned(), - 1000, - ) - }) - .unwrap(); - - // verify contract data are as expected - let contract_data = keeper.load_contract(&wasm_storage, &contract_addr).unwrap(); - - assert_eq!( - contract_data, - ContractData { - code_id, - creator: Addr::unchecked("foobar"), - admin: Some(Addr::unchecked("admin")), - label: "label".to_owned(), - created: 1000, - } - ); - - let err = transactional(&mut wasm_storage, |cache, _| { - // now, we call this contract and see the error message from the contract - let info = mock_info("foobar", &[]); - keeper.call_instantiate( - contract_addr.clone(), - &api, - cache, - &mock_router(), - &block, - info, - b"{}".to_vec(), - ) - }) - .unwrap_err(); - - // StdError from contract_error auto-converted to string - assert_eq!( - StdError::generic_err("Init failed"), - err.downcast().unwrap() - ); - - let err = transactional(&mut wasm_storage, |cache, _| { - // and the error for calling an unregistered contract - let info = mock_info("foobar", &[]); - keeper.call_instantiate( - Addr::unchecked("unregistered"), - &api, - cache, - &mock_router(), - &block, - info, - b"{}".to_vec(), - ) - }) - .unwrap_err(); - - // Default error message from router when not found - assert_eq!( - StdError::not_found("cw_multi_test::wasm::ContractData"), - err.downcast().unwrap() - ); - } - - #[test] - fn query_contract_into() { - let api = MockApi::default(); - let mut keeper = WasmKeeper::::new(); - let block = mock_env().block; - let code_id = keeper.store_code(payout::contract()); - - let mut wasm_storage = MockStorage::new(); - - let contract_addr = keeper - .register_contract( - &mut wasm_storage, - code_id, - Addr::unchecked("foobar"), - Addr::unchecked("admin"), - "label".to_owned(), - 1000, - ) - .unwrap(); - - let querier: MockQuerier = MockQuerier::new(&[]); - let query = WasmQuery::ContractInfo { - contract_addr: contract_addr.to_string(), - }; - let info = keeper - .query(&api, &wasm_storage, &querier, &block, query) - .unwrap(); - - let mut expected = ContractInfoResponse::new(code_id as u64, "foobar"); - expected.admin = Some("admin".to_owned()); - assert_eq!(expected, from_slice(&info).unwrap()); - } - - #[test] - fn can_dump_raw_wasm_state() { - let api = MockApi::default(); - let mut keeper = WasmKeeper::::new(); - let block = mock_env().block; - let code_id = keeper.store_code(payout::contract()); - - let mut wasm_storage = MockStorage::new(); - - let contract_addr = keeper - .register_contract( - &mut wasm_storage, - code_id, - Addr::unchecked("foobar"), - Addr::unchecked("admin"), - "label".to_owned(), - 1000, - ) - .unwrap(); - - // make a contract with state - let payout = coin(1500, "mlg"); - let msg = payout::InstantiateMessage { - payout: payout.clone(), - }; - keeper - .call_instantiate( - contract_addr.clone(), - &api, - &mut wasm_storage, - &mock_router(), - &block, - mock_info("foobar", &[]), - to_vec(&msg).unwrap(), - ) - .unwrap(); - - // dump state - let state = keeper.dump_wasm_raw(&wasm_storage, &contract_addr); - assert_eq!(state.len(), 2); - // check contents - let (k, v) = &state[0]; - assert_eq!(k.as_slice(), b"count"); - let count: u32 = from_slice(v).unwrap(); - assert_eq!(count, 1); - let (k, v) = &state[1]; - assert_eq!(k.as_slice(), b"payout"); - let stored_pay: payout::InstantiateMessage = from_slice(v).unwrap(); - assert_eq!(stored_pay.payout, payout); - } - - #[test] - fn contract_send_coins() { - let api = MockApi::default(); - let mut keeper = WasmKeeper::new(); - let block = mock_env().block; - let code_id = keeper.store_code(payout::contract()); - - let mut wasm_storage = MockStorage::new(); - let mut cache = StorageTransaction::new(&wasm_storage); - - let contract_addr = keeper - .register_contract( - &mut cache, - code_id, - Addr::unchecked("foobar"), - None, - "label".to_owned(), - 1000, - ) - .unwrap(); - - let payout = coin(100, "TGD"); - - // init the contract - let info = mock_info("foobar", &[]); - let init_msg = to_vec(&payout::InstantiateMessage { - payout: payout.clone(), - }) - .unwrap(); - let res = keeper - .call_instantiate( - contract_addr.clone(), - &api, - &mut cache, - &mock_router(), - &block, - info, - init_msg, - ) - .unwrap(); - assert_eq!(0, res.messages.len()); - - // execute the contract - let info = mock_info("foobar", &[]); - let res = keeper - .call_execute( - &api, - &mut cache, - contract_addr.clone(), - &mock_router(), - &block, - info, - b"{}".to_vec(), - ) - .unwrap(); - assert_eq!(1, res.messages.len()); - match &res.messages[0].msg { - CosmosMsg::Bank(BankMsg::Send { to_address, amount }) => { - assert_eq!(to_address.as_str(), "foobar"); - assert_eq!(amount.as_slice(), &[payout.clone()]); - } - m => panic!("Unexpected message {:?}", m), - } - - // and flush before query - cache.prepare().commit(&mut wasm_storage); - - // query the contract - let query = to_vec(&payout::QueryMsg::Payout {}).unwrap(); - let querier: MockQuerier = MockQuerier::new(&[]); - let data = keeper - .query_smart(contract_addr, &api, &wasm_storage, &querier, &block, query) - .unwrap(); - let res: payout::InstantiateMessage = from_slice(&data).unwrap(); - assert_eq!(res.payout, payout); - } - - fn assert_payout( - router: &WasmKeeper, - storage: &mut dyn Storage, - contract_addr: &Addr, - payout: &Coin, - ) { - let api = MockApi::default(); - let info = mock_info("silly", &[]); - let res = router - .call_execute( - &api, - storage, - contract_addr.clone(), - &mock_router(), - &mock_env().block, - info, - b"{}".to_vec(), - ) - .unwrap(); - assert_eq!(1, res.messages.len()); - match &res.messages[0].msg { - CosmosMsg::Bank(BankMsg::Send { to_address, amount }) => { - assert_eq!(to_address.as_str(), "silly"); - assert_eq!(amount.as_slice(), &[payout.clone()]); - } - m => panic!("Unexpected message {:?}", m), - } - } - - fn assert_no_contract(storage: &dyn Storage, contract_addr: &Addr) { - let contract = CONTRACTS.may_load(storage, contract_addr).unwrap(); - assert!(contract.is_none(), "{:?}", contract_addr); - } - - #[test] - fn multi_level_wasm_cache() { - let api = MockApi::default(); - let mut keeper = WasmKeeper::new(); - let block = mock_env().block; - let code_id = keeper.store_code(payout::contract()); - - let mut wasm_storage = MockStorage::new(); - - let payout1 = coin(100, "TGD"); - - // set contract 1 and commit (on router) - let contract1 = transactional(&mut wasm_storage, |cache, _| { - let contract = keeper - .register_contract( - cache, - code_id, - Addr::unchecked("foobar"), - None, - "".to_string(), - 1000, - ) - .unwrap(); - let info = mock_info("foobar", &[]); - let init_msg = to_vec(&payout::InstantiateMessage { - payout: payout1.clone(), - }) - .unwrap(); - keeper - .call_instantiate( - contract.clone(), - &api, - cache, - &mock_router(), - &block, - info, - init_msg, - ) - .unwrap(); - - Ok(contract) - }) - .unwrap(); - - let payout2 = coin(50, "BTC"); - let payout3 = coin(1234, "ATOM"); - - // create a new cache and check we can use contract 1 - let (contract2, contract3) = transactional(&mut wasm_storage, |cache, wasm_reader| { - assert_payout(&keeper, cache, &contract1, &payout1); - - // create contract 2 and use it - let contract2 = keeper - .register_contract( - cache, - code_id, - Addr::unchecked("foobar"), - None, - "".to_owned(), - 1000, - ) - .unwrap(); - let info = mock_info("foobar", &[]); - let init_msg = to_vec(&payout::InstantiateMessage { - payout: payout2.clone(), - }) - .unwrap(); - let _res = keeper - .call_instantiate( - contract2.clone(), - &api, - cache, - &mock_router(), - &block, - info, - init_msg, - ) - .unwrap(); - assert_payout(&keeper, cache, &contract2, &payout2); - - // create a level2 cache and check we can use contract 1 and contract 2 - let contract3 = transactional(cache, |cache2, read| { - assert_payout(&keeper, cache2, &contract1, &payout1); - assert_payout(&keeper, cache2, &contract2, &payout2); - - // create a contract on level 2 - let contract3 = keeper - .register_contract( - cache2, - code_id, - Addr::unchecked("foobar"), - None, - "".to_owned(), - 1000, - ) - .unwrap(); - let info = mock_info("johnny", &[]); - let init_msg = to_vec(&payout::InstantiateMessage { - payout: payout3.clone(), - }) - .unwrap(); - let _res = keeper - .call_instantiate( - contract3.clone(), - &api, - cache2, - &mock_router(), - &block, - info, - init_msg, - ) - .unwrap(); - assert_payout(&keeper, cache2, &contract3, &payout3); - - // ensure first cache still doesn't see this contract - assert_no_contract(read, &contract3); - Ok(contract3) - }) - .unwrap(); - - // after applying transaction, all contracts present on cache - assert_payout(&keeper, cache, &contract1, &payout1); - assert_payout(&keeper, cache, &contract2, &payout2); - assert_payout(&keeper, cache, &contract3, &payout3); - - // but not yet the root router - assert_no_contract(wasm_reader, &contract1); - assert_no_contract(wasm_reader, &contract2); - assert_no_contract(wasm_reader, &contract3); - - Ok((contract2, contract3)) - }) - .unwrap(); - - // ensure that it is now applied to the router - assert_payout(&keeper, &mut wasm_storage, &contract1, &payout1); - assert_payout(&keeper, &mut wasm_storage, &contract2, &payout2); - assert_payout(&keeper, &mut wasm_storage, &contract3, &payout3); - } - - fn assert_admin( - storage: &dyn Storage, - keeper: &WasmKeeper, - contract_addr: &impl ToString, - admin: Option, - ) { - let api = MockApi::default(); - let querier: MockQuerier = MockQuerier::new(&[]); - // query - let data = keeper - .query( - &api, - storage, - &querier, - &mock_env().block, - WasmQuery::ContractInfo { - contract_addr: contract_addr.to_string(), - }, - ) - .unwrap(); - let res: ContractInfoResponse = from_slice(&data).unwrap(); - assert_eq!(res.admin, admin.as_ref().map(Addr::to_string)); - } - - #[test] - fn update_clear_admin_works() { - let api = MockApi::default(); - let mut keeper = WasmKeeper::new(); - let block = mock_env().block; - let code_id = keeper.store_code(caller::contract()); - - let mut wasm_storage = MockStorage::new(); - - let admin: Addr = Addr::unchecked("admin"); - let new_admin: Addr = Addr::unchecked("new_admin"); - let normal_user: Addr = Addr::unchecked("normal_user"); - - let contract_addr = keeper - .register_contract( - &mut wasm_storage, - code_id, - Addr::unchecked("creator"), - admin.clone(), - "label".to_owned(), - 1000, - ) - .unwrap(); - - // init the contract - let info = mock_info("admin", &[]); - let init_msg = to_vec(&EmptyMsg {}).unwrap(); - let res = keeper - .call_instantiate( - contract_addr.clone(), - &api, - &mut wasm_storage, - &mock_router(), - &block, - info, - init_msg, - ) - .unwrap(); - assert_eq!(0, res.messages.len()); - - assert_admin(&wasm_storage, &keeper, &contract_addr, Some(admin.clone())); - - // non-admin should not be allowed to become admin on their own - keeper - .execute_wasm( - &api, - &mut wasm_storage, - &mock_router(), - &block, - normal_user.clone(), - WasmMsg::UpdateAdmin { - contract_addr: contract_addr.to_string(), - admin: normal_user.to_string(), - }, - ) - .unwrap_err(); - - // should still be admin - assert_admin(&wasm_storage, &keeper, &contract_addr, Some(admin.clone())); - - // admin should be allowed to transfers adminship - let res = keeper - .execute_wasm( - &api, - &mut wasm_storage, - &mock_router(), - &block, - admin, - WasmMsg::UpdateAdmin { - contract_addr: contract_addr.to_string(), - admin: new_admin.to_string(), - }, - ) - .unwrap(); - assert_eq!(res.events.len(), 0); - - // new_admin should now be admin - assert_admin( - &wasm_storage, - &keeper, - &contract_addr, - Some(new_admin.clone()), - ); - - // new_admin should now be able to clear to admin - let res = keeper - .execute_wasm( - &api, - &mut wasm_storage, - &mock_router(), - &block, - new_admin, - WasmMsg::ClearAdmin { - contract_addr: contract_addr.to_string(), - }, - ) - .unwrap(); - assert_eq!(res.events.len(), 0); - - // should have no admin now - assert_admin(&wasm_storage, &keeper, &contract_addr, None); - } -} diff --git a/packages/storage-macro/Cargo.toml b/packages/storage-macro/Cargo.toml deleted file mode 100644 index 39eceef0c..000000000 --- a/packages/storage-macro/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "cw-storage-macro" -version = "0.16.0" -authors = ["yoisha <48324733+y-pakorn@users.noreply.github.com>"] -edition = "2018" -description = "Macro helpers for storage-plus" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -proc-macro = true - -[dependencies] -syn = { version = "1.0.96", features = ["full"] } - -[dev-dependencies] -cosmwasm-std = { version = "1.1.0", default-features = false } -serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/storage-macro/NOTICE b/packages/storage-macro/NOTICE deleted file mode 100644 index 4ae1ccfe5..000000000 --- a/packages/storage-macro/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW-Storage-Macro: Macro helpers for storage-plus -Copyright (C) 2022 Confio GmbH - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/storage-macro/README.md b/packages/storage-macro/README.md deleted file mode 100644 index d21d9f571..000000000 --- a/packages/storage-macro/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# CW-Storage-Plus: Macro helpers for storage-plus - -Procedural macros helper for interacting with cw-storage-plus and cosmwasm-storage. - -## Current features - -Auto generate an `IndexList` impl for your indexes struct. - -```rust -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct TestStruct { - id: u64, - id2: u32, - addr: Addr, -} - -#[index_list(TestStruct)] // <- Add this line right here. -struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, -} -``` diff --git a/packages/storage-macro/src/lib.rs b/packages/storage-macro/src/lib.rs deleted file mode 100644 index 23ecc5c5f..000000000 --- a/packages/storage-macro/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -/*! -Procedural macros helper for interacting with cw-storage-plus and cosmwasm-storage. - -For more information on this package, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/storage-macro/README.md). -*/ - -use proc_macro::TokenStream; -use syn::{ - Ident, - __private::{quote::quote, Span}, - parse_macro_input, ItemStruct, -}; - -#[proc_macro_attribute] -pub fn index_list(attr: TokenStream, item: TokenStream) -> TokenStream { - let input = parse_macro_input!(item as ItemStruct); - - let ty = Ident::new(&attr.to_string(), Span::call_site()); - let struct_ty = input.ident.clone(); - - let names = input - .fields - .clone() - .into_iter() - .map(|e| { - let name = e.ident.unwrap(); - quote! { &self.#name } - }) - .collect::>(); - - let expanded = quote! { - #input - - impl cw_storage_plus::IndexList<#ty> for #struct_ty<'_> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn cw_storage_plus::Index<#ty>> = vec![#(#names),*]; - Box::new(v.into_iter()) - } - } - }; - - TokenStream::from(expanded) -} diff --git a/packages/storage-plus/Cargo.toml b/packages/storage-plus/Cargo.toml deleted file mode 100644 index 2855094c2..000000000 --- a/packages/storage-plus/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "cw-storage-plus" -version = "0.16.0" -authors = ["Ethan Frey "] -edition = "2018" -description = "Enhanced storage engines" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -[package.metadata.docs.rs] -all-features = true # include macro feature when building docs - -[features] -default = ["iterator"] -iterator = ["cosmwasm-std/iterator"] -macro = ["cw-storage-macro"] - -[lib] -# See https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options -bench = false - -[dependencies] -cosmwasm-std = { version = "1.1.0", default-features = false } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw-storage-macro = { version = "0.16.0", optional = true, path = "../storage-macro" } - -[dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -rand = "0.8" - -[[bench]] -name = "main" -harness = false diff --git a/packages/storage-plus/NOTICE b/packages/storage-plus/NOTICE deleted file mode 100644 index 838a67f47..000000000 --- a/packages/storage-plus/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW-Storage-Plus: Enhanced/experimental storage engines for CosmWasm -Copyright (C) 2020 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/storage-plus/README.md b/packages/storage-plus/README.md deleted file mode 100644 index b87b84223..000000000 --- a/packages/storage-plus/README.md +++ /dev/null @@ -1,702 +0,0 @@ -# CW-Storage-Plus: Enhanced storage engines for CosmWasm - -After building `cosmwasm-storage`, we realized many of the design decisions were -limiting us and producing a lot of needless boilerplate. The decision was made to leave -those APIs stable for anyone wanting a very basic abstraction on the KV-store and to -build a much more powerful and complex ORM layer that can provide powerful accessors -using complex key types, which are transparently turned into bytes. - -This led to a number of breaking API changes in this package of the course of several -releases as we updated this with lots of experience, user feedback, and deep dives to harness -the full power of generics. - -**Status: beta** - -As of `cw-storage-plus` `v0.12` the API should be quite stable. -There are no major API breaking issues pending, and all API changes will be documented -in [`MIGRATING.md`](../../MIGRATING.md). - -This has been heavily used in many production-quality contracts. -The code has demonstrated itself to be stable and powerful. -It has not been audited, and Confio assumes no liability, but we consider it mature enough -to be the **standard storage layer** for your contracts. - -## Usage Overview - -We introduce two main classes to provide a productive abstraction -on top of `cosmwasm_std::Storage`. They are `Item`, which is -a typed wrapper around one database key, providing some helper functions -for interacting with it without dealing with raw bytes. And `Map`, -which allows you to store multiple unique typed objects under a prefix, -indexed by a simple or compound (eg. `(&[u8], &[u8])`) primary key. - -## Item - -The usage of an [`Item`](./src/item.rs) is pretty straight-forward. -You must simply provide the proper type, as well as a database key not -used by any other item. Then it will provide you with a nice interface -to interact with such data. - -If you are coming from using `Singleton`, the biggest change is that -we no longer store `Storage` inside, meaning we don't need read and write -variants of the object, just one type. Furthermore, we use `const fn` -to create the `Item`, allowing it to be defined as a global compile-time -constant rather than a function that must be constructed each time, -which saves gas as well as typing. - -Example Usage: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug)] -struct Config { - pub owner: String, - pub max_tokens: i32, -} - -// note const constructor rather than 2 functions with Singleton -const CONFIG: Item = Item::new("config"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // may_load returns Option, so None if data is missing - // load returns T and Err(StdError::NotFound{}) if data is missing - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg)?; - let loaded = CONFIG.load(&store)?; - assert_eq!(cfg, loaded); - - // update an item with a closure (includes read and write) - // returns the newly saved value - let output = CONFIG.update(&mut store, |mut c| -> StdResult<_> { - c.max_tokens *= 2; - Ok(c) - })?; - assert_eq!(2468, output.max_tokens); - - // you can error in an update and nothing is saved - let failed = CONFIG.update(&mut store, |_| -> StdResult<_> { - Err(StdError::generic_err("failure mode")) - }); - assert!(failed.is_err()); - - // loading data will show the first update was saved - let loaded = CONFIG.load(&store)?; - let expected = Config { - owner: "admin".to_string(), - max_tokens: 2468, - }; - assert_eq!(expected, loaded); - - // we can remove data as well - CONFIG.remove(&mut store); - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - - Ok(()) -} -``` - -## Map - -The usage of a [`Map`](./src/map.rs) is a little more complex, but -is still pretty straight-forward. You can imagine it as a storage-backed -`BTreeMap`, allowing key-value lookups with typed values. In addition, -we support not only simple binary keys (like `&[u8]`), but tuples, which are -combined. This allows us by example to store allowances as composite keys, -i.e. `(owner, spender)` to look up the balance. - -Beyond direct lookups, we have a super-power not found in Ethereum - -iteration. That's right, you can list all items in a `Map`, or only -part of them. We can efficiently allow pagination over these items as -well, starting at the point the last query ended, with low gas costs. -This requires the `iterator` feature to be enabled in `cw-storage-plus` -(which automatically enables it in `cosmwasm-std` as well, and which is -enabled by default). - -If you are coming from using `Bucket`, the biggest change is that -we no longer store `Storage` inside, meaning we don't need read and write -variants of the object, just one type. Furthermore, we use `const fn` -to create the `Bucket`, allowing it to be defined as a global compile-time -constant rather than a function that must be constructed each time, -which saves gas as well as typing. In addition, the composite indexes -(tuples) are more ergonomic and expressive of intention, and the range -interface has been improved. - -Here is an example with normal (simple) keys: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // load and save with extra key argument - let empty = PEOPLE.may_load(&store, "john")?; - assert_eq!(None, empty); - PEOPLE.save(&mut store, "john", &data)?; - let loaded = PEOPLE.load(&store, "john")?; - assert_eq!(data, loaded); - - // nothing on another key - let missing = PEOPLE.may_load(&store, "jack")?; - assert_eq!(None, missing); - - // update function for new or existing keys - let birthday = |d: Option| -> StdResult { - match d { - Some(one) => Ok(Data { - name: one.name, - age: one.age + 1, - }), - None => Ok(Data { - name: "Newborn".to_string(), - age: 0, - }), - } - }; - - let old_john = PEOPLE.update(&mut store, "john", birthday)?; - assert_eq!(33, old_john.age); - assert_eq!("John", old_john.name.as_str()); - - let new_jack = PEOPLE.update(&mut store, "jack", birthday)?; - assert_eq!(0, new_jack.age); - assert_eq!("Newborn", new_jack.name.as_str()); - - // update also changes the store - assert_eq!(old_john, PEOPLE.load(&store, "john")?); - assert_eq!(new_jack, PEOPLE.load(&store, "jack")?); - - // removing leaves us empty - PEOPLE.remove(&mut store, "john"); - let empty = PEOPLE.may_load(&store, "john")?; - assert_eq!(None, empty); - - Ok(()) -} -``` - -### Key types - -A `Map` key can be anything that implements the `PrimaryKey` trait. There are a series of implementations of -`PrimaryKey` already provided (see [keys.rs](./src/keys.rs)): - - - `impl<'a> PrimaryKey<'a> for &'a [u8]` - - `impl<'a> PrimaryKey<'a> for &'a str` - - `impl<'a> PrimaryKey<'a> for Vec` - - `impl<'a> PrimaryKey<'a> for String` - - `impl<'a> PrimaryKey<'a> for Addr` - - `impl<'a> PrimaryKey<'a> for &'a Addr` - - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a>> PrimaryKey<'a> for (T, U)` - - `impl<'a, T: PrimaryKey<'a> + Prefixer<'a>, U: PrimaryKey<'a> + Prefixer<'a>, V: PrimaryKey<'a>> PrimaryKey<'a> for (T, U, V)` - - `PrimaryKey` implemented for unsigned integers up to `u128` - - `PrimaryKey` implemented for signed integers up to `i128` - -That means that byte and string slices, byte vectors, and strings, can be conveniently used as keys. -Moreover, some other types can be used as well, like addresses and address references, pairs, triples, and -integer types. - -If the key represents an address, we suggest using `&Addr` for keys in storage, instead of `String` or string slices. -This implies doing address validation through `addr_validate` on any address passed in via a message, to ensure it's a -legitimate address, and not random text which will fail later. -`pub fn addr_validate(&self, &str) -> Addr` in `deps.api` can be used for address validation, and the returned `Addr` -can then be conveniently used as key in a `Map` or similar structure. - -It's also convenient to use references (i.e. borrowed values) instead of values for keys (i.e. `&Addr` instead of `Addr`), -as that will typically save some cloning during key reading / writing. - -### Composite Keys - -There are times when we want to use multiple items as a key. For example, when -storing allowances based on account owner and spender. We could try to manually -concatenate them before calling, but that can lead to overlap, and is a bit -low-level for us. Also, by explicitly separating the keys, we can easily provide -helpers to do range queries over a prefix, such as "show me all allowances for -one owner" (first part of the composite key). Just like you'd expect from your -favorite database. - -Here's how we use it with composite keys. Just define a tuple as a key and use that -everywhere you used a single key above. - -```rust -// Note the tuple for primary key. We support one slice, or a 2 or 3-tuple. -// Adding longer tuples is possible, but unlikely to be needed. -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // save and load on a composite key - let empty = ALLOWANCE.may_load(&store, ("owner", "spender"))?; - assert_eq!(None, empty); - ALLOWANCE.save(&mut store, ("owner", "spender"), &777)?; - let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; - assert_eq!(777, loaded); - - // doesn't appear under other key (even if a concat would be the same) - let different = ALLOWANCE.may_load(&store, ("owners", "pender")).unwrap(); - assert_eq!(None, different); - - // simple update - ALLOWANCE.update(&mut store, ("owner", "spender"), |v| { - Ok(v.unwrap_or_default() + 222) - })?; - let loaded = ALLOWANCE.load(&store, ("owner", "spender"))?; - assert_eq!(999, loaded); - - Ok(()) -} -``` - -### Path - -Under the scenes, we create a `Path` from the `Map` when accessing a key. -`PEOPLE.load(&store, "jack") == PEOPLE.key("jack").load()`. -`Map.key()` returns a `Path`, which has the same interface as `Item`, -re-using the calculated path to this key. - -For simple keys, this is just a bit less typing and a bit less gas if you -use the same key for many calls. However, for composite keys, like -`("owner", "spender")` it is **much** less typing. And highly recommended anywhere -you will use a composite key even twice: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // create a Path one time to use below - let john = PEOPLE.key("john"); - - // Use this just like an Item above - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - john.save(&mut store, &data)?; - let loaded = john.load(&store)?; - assert_eq!(data, loaded); - john.remove(&mut store); - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - - // Same for composite keys, just use both parts in `key()`. - // Notice how much less verbose than the above example. - let allow = ALLOWANCE.key(("owner", "spender")); - allow.save(&mut store, &1234)?; - let loaded = allow.load(&store)?; - assert_eq!(1234, loaded); - allow.update(&mut store, |x| Ok(x.unwrap_or_default() * 2))?; - let loaded = allow.load(&store)?; - assert_eq!(2468, loaded); - - Ok(()) -} -``` - -### Prefix - -In addition to getting one particular item out of a map, we can iterate over the map -(or a subset of the map). This let us answer questions like "show me all tokens", -and we provide some nice [`Bound`](#bound) helpers to easily allow pagination or custom ranges. - -The general format is to get a `Prefix` by calling `map.prefix(k)`, where `k` is exactly -one less item than the normal key (If `map.key()` took `(&[u8], &[u8])`, then `map.prefix()` takes `&[u8]`. -If `map.key()` took `&[u8]`, `map.prefix()` takes `()`). Once we have a prefix space, we can iterate -over all items with `range(store, min, max, order)`. It supports `Order::Ascending` or `Order::Descending`. -`min` is the lower bound and `max` is the higher bound. - -If the `min` and `max` bounds are `None`, `range` will return all items under the prefix. You can use `.take(n)` to -limit the results to `n` items and start doing pagination. You can also set the `min` bound to -eg. `Bound::exclusive(last_value)` to start iterating over all items *after* the last value. Combined with -`take`, we easily have pagination support. You can also use `Bound::inclusive(x)` when you want to include any -perfect matches. - -### Bound - -`Bound` is a helper to build type-safe bounds on the keys or sub-keys you want to iterate over. -It also supports a raw (`Vec`) bounds specification, for the cases you don't want or can't use typed bounds. - -```rust -#[derive(Clone, Debug)] -pub enum Bound<'a, K: PrimaryKey<'a>> { - Inclusive((K, PhantomData<&'a bool>)), - Exclusive((K, PhantomData<&'a bool>)), - InclusiveRaw(Vec), - ExclusiveRaw(Vec), -} -``` - -To better understand the API, please check the following example: -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const PEOPLE: Map<&str, Data> = Map::new("people"); -const ALLOWANCE: Map<(&str, &str), u64> = Map::new("allow"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // save and load on two keys - let data = Data { name: "John".to_string(), age: 32 }; - PEOPLE.save(&mut store, "john", &data)?; - let data2 = Data { name: "Jim".to_string(), age: 44 }; - PEOPLE.save(&mut store, "jim", &data2)?; - - // iterate over them all - let all: StdResult> = PEOPLE - .range(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![("jim".to_vec(), data2), ("john".to_vec(), data.clone())] - ); - - // or just show what is after jim - let all: StdResult> = PEOPLE - .range( - &store, - Some(Bound::exclusive("jim")), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(all?, vec![("john".to_vec(), data)]); - - // save and load on three keys, one under different owner - ALLOWANCE.save(&mut store, ("owner", "spender"), &1000)?; - ALLOWANCE.save(&mut store, ("owner", "spender2"), &3000)?; - ALLOWANCE.save(&mut store, ("owner2", "spender"), &5000)?; - - // get all under one key - let all: StdResult> = ALLOWANCE - .prefix("owner") - .range(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![("spender".to_vec(), 1000), ("spender2".to_vec(), 3000)] - ); - - // Or ranges between two items (even reverse) - let all: StdResult> = ALLOWANCE - .prefix("owner") - .range( - &store, - Some(Bound::exclusive("spender")), - Some(Bound::inclusive("spender2")), - Order::Descending, - ) - .collect(); - assert_eq!(all?, vec![("spender2".to_vec(), 3000)]); - - Ok(()) -} -``` - -**NB**: For properly defining and using type-safe bounds over a `MultiIndex`, see [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), -below. - -## IndexedMap - -Let's see one example of `IndexedMap` definition and usage, originally taken from the `cw721-base` contract. - -### Definition - -```rust -pub struct TokenIndexes<'a> { - pub owner: MultiIndex<'a, Addr, TokenInfo, String>, -} - -impl<'a> IndexList for TokenIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.owner]; - Box::new(v.into_iter()) - } -} - -pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { - let indexes = TokenIndexes { - owner: MultiIndex::new( - |d: &TokenInfo| d.owner.clone(), - "tokens", - "tokens__owner", - ), - }; - IndexedMap::new("tokens", indexes) -} -``` - -Let's discuss this piece by piece: -```rust -pub struct TokenIndexes<'a> { - pub owner: MultiIndex<'a, Addr, TokenInfo, String>, -} -``` - -These are the index definitions. Here there's only one index, called `owner`. There could be more, as public -members of the `TokenIndexes` struct. -We see that the `owner` index is a `MultiIndex`. A multi-index can have repeated values as keys. The primary key is -used internally as the last element of the multi-index key, to disambiguate repeated index values. -Like the name implies, this is an index over tokens, by owner. Given that an owner can have multiple tokens, -we need a `MultiIndex` to be able to list / iterate over all the tokens he has. - -The `TokenInfo` data will originally be stored by `token_id` (which is a string value). -You can see this in the token creation code: -```rust - tokens().update(deps.storage, &msg.token_id, |old| match old { - Some(_) => Err(ContractError::Claimed {}), - None => Ok(token), - })?; -``` -(Incidentally, this is using `update` instead of `save`, to avoid overwriting an already existing token). - -Given that `token_id` is a string value, we specify `String` as the last argument of the `MultiIndex` definition. -That way, the deserialization of the primary key will be done to the right type (an owned string). - -**NB**: In the particular case of a `MultiIndex`, and with the latest implementation of type-safe bounds, the definition of -this last type parameter is crucial, for properly using type-safe bounds. -See [Type-safe bounds over `MultiIndex`](#type-safe-bounds-over-multiindex), below. - -Then, this `TokenInfo` data will be indexed by token `owner` (which is an `Addr`). So that we can list all the tokens -an owner has. That's why the `owner` index key is `Addr`. - -Other important thing here is that the key (and its components, in the case of a composite key) must implement -the `PrimaryKey` trait. You can see that `Addr` does implement `PrimaryKey`: - -```rust -impl<'a> PrimaryKey<'a> for Addr { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self.as_bytes())] - } -} -``` - ---- - -We can now see how it all works, taking a look at the remaining code: - -```rust -impl<'a> IndexList for TokenIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.owner]; - Box::new(v.into_iter()) - } -} -``` - -This implements the `IndexList` trait for `TokenIndexes`. - -**NB**: this code is more or less boiler-plate, and needed for the internals. Do not try to customize this; -just return a list of all indexes. -Implementing this trait serves two purposes (which are really one and the same): it allows the indexes -to be queried through `get_indexes`, and, it allows `TokenIndexes` to be treated as an `IndexList`. So that -it can be passed as a parameter during `IndexedMap` construction, below: - -```rust -pub fn tokens<'a>() -> IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a>> { - let indexes = TokenIndexes { - owner: MultiIndex::new( - |d: &TokenInfo| d.owner.clone(), - "tokens", - "tokens__owner", - ), - }; - IndexedMap::new("tokens", indexes) -} -``` - -Here `tokens()` is just a helper function, that simplifies the `IndexedMap` construction for us. First the -index (es) is (are) created, and then, the `IndexedMap` is created and returned. - -During index creation, we must supply an index function per index -```rust - owner: MultiIndex::new(|d: &TokenInfo| d.owner.clone(), -``` -which is the one that will take the value of the original map and create the index key from it. -Of course, this requires that the elements required for the index key are present in the value. -Besides the index function, we must also supply the namespace of the pk, and the one for the new index. - ---- - -After that, we just create and return the `IndexedMap`: - -```rust - IndexedMap::new("tokens", indexes) -``` - -Here of course, the namespace of the pk must match the one used during index(es) creation. And, we pass our -`TokenIndexes` (as an `IndexList`-type parameter) as second argument. Connecting in this way the underlying `Map` -for the pk, with the defined indexes. - -So, `IndexedMap` (and the other `Indexed*` types) is just a wrapper / extension around `Map`, that provides -a number of index functions and namespaces to create indexes over the original `Map` data. It also implements -calling these index functions during value storage / update / removal, so that you can forget about it, -and just use the indexed data. - -### Usage - -An example of use, where `owner` is a `String` value passed as a parameter, and `start_after` and `limit` optionally -define the pagination range: - -Notice this uses `prefix()`, explained above in the `Map` section. - -```rust - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); - let owner_addr = deps.api.addr_validate(&owner)?; - - let res: Result, _> = tokens() - .idx - .owner - .prefix(owner_addr) - .range(deps.storage, start, None, Order::Ascending) - .take(limit) - .collect(); - let tokens = res?; -``` -Now `tokens` contains `(token_id, TokenInfo)` pairs for the given `owner`. -The pk values are `Vec` in the case of `range_raw()`, but will be deserialized to the proper type using -`range()`; provided that the pk deserialization type (`String`, in this case) is correctly specified -in the `MultiIndex` definition (see [Index keys deserialization](#index-keys-deserialization), -below). - -Another example that is similar, but returning only the (raw) `token_id`s, using the `keys_raw()` method: -```rust - let pks: Vec<_> = tokens() - .idx - .owner - .prefix(owner_addr) - .keys_raw( - deps.storage, - start, - None, - Order::Ascending, - ) - .take(limit) - .collect(); -``` -Now `pks` contains `token_id` values (as raw `Vec`s) for the given `owner`. By using `keys` instead, -a deserialized key can be obtained, as detailed in the next section. - -### Index keys deserialization - -For `UniqueIndex` and `MultiIndex`, the primary key (`PK`) type needs to be specified, in order to deserialize -the primary key to it. -This `PK` type specification is also important for `MultiIndex` type-safe bounds, as the primary key -is part of the multi-index key. See next section, [Type-safe bounds over MultiIndex](#type-safe-bounds-over-multiindex). - -**NB**: This specification is still a manual (and therefore error-prone) process / setup, that will (if possible) -be automated in the future (https://github.com/CosmWasm/cw-plus/issues/531). - -### Type-safe bounds over MultiIndex - -In the particular case of `MultiIndex`, the primary key (`PK`) type parameter also defines the type of the (partial) bounds over -the index key (the part that corresponds to the primary key, that is). -So, to correctly use type-safe bounds over multi-indexes ranges, it is fundamental for this `PK` type -to be correctly defined, so that it matches the primary key type, or its (typically owned) deserialization variant. - -## VecDeque - -The usage of a [`VecDeque`](./src/deque.rs) is pretty straight-forward. -Conceptually it works like a storage-backed version of Rust std's `VecDeque` and can be used as a queue or stack. -It allows you to push and pop elements on both ends and also read the first or last element without mutating the deque. -You can also read a specific index directly. - -Example Usage: - -```rust -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Data { - pub name: String, - pub age: i32, -} - -const DATA: Deque = Deque::new("data"); - -fn demo() -> StdResult<()> { - let mut store = MockStorage::new(); - - // read methods return a wrapped Option, so None if the deque is empty - let empty = DATA.front(&store)?; - assert_eq!(None, empty); - - // some example entries - let p1 = Data { - name: "admin".to_string(), - age: 1234, - }; - let p2 = Data { - name: "user".to_string(), - age: 123, - }; - - // use it like a queue by pushing and popping at opposite ends - DATA.push_back(&mut store, &p1)?; - DATA.push_back(&mut store, &p2)?; - - let admin = DATA.pop_front(&mut store)?; - assert_eq!(admin.as_ref(), Some(&p1)); - let user = DATA.pop_front(&mut store)?; - assert_eq!(user.as_ref(), Some(&p2)); - - // or push and pop at the same end to use it as a stack - DATA.push_back(&mut store, &p1)?; - DATA.push_back(&mut store, &p2)?; - - let user = DATA.pop_back(&mut store)?; - assert_eq!(user.as_ref(), Some(&p2)); - let admin = DATA.pop_back(&mut store)?; - assert_eq!(admin.as_ref(), Some(&p1)); - - // you can also iterate over it - DATA.push_front(&mut store, &p1)?; - DATA.push_front(&mut store, &p2)?; - - let all: StdResult> = DATA.iter(&store)?.collect(); - assert_eq!(all?, [p2, p1]); - - // or access an index directly - assert_eq!(DATA.get(&store, 0)?, Some(p2)); - assert_eq!(DATA.get(&store, 1)?, Some(p1)); - assert_eq!(DATA.get(&store, 3)?, None); - - Ok(()) -} -``` diff --git a/packages/storage-plus/benches/main.rs b/packages/storage-plus/benches/main.rs deleted file mode 100644 index a0623257f..000000000 --- a/packages/storage-plus/benches/main.rs +++ /dev/null @@ -1,161 +0,0 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; - -use rand::Rng; -use std::mem; -use std::time::Duration; - -use cw_storage_plus::IntKey; - -fn bench_signed_int_key(c: &mut Criterion) { - let mut group = c.benchmark_group("Signed int keys"); - - fn k() -> i32 { - // let k: i32 = 0x42434445; - // k - rand::thread_rng().gen_range(i32::MIN..i32::MAX) - } - // For the asserts - let k_check = k(); - - type Buf = [u8; mem::size_of::()]; - - group.bench_function("i32 to_cw_bytes: xored (u32) + to_be_bytes", |b| { - #[inline] - fn to_cw_bytes(value: &i32) -> Buf { - (*value as u32 ^ i32::MIN as u32).to_be_bytes() - } - - assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!( - to_cw_bytes(&k_check.wrapping_neg()), - i32::to_cw_bytes(&k_check.wrapping_neg()) - ); - - b.iter(|| { - let k = k(); - black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&k.wrapping_neg())); - }); - }); - - group.bench_function("i32 to_cw_bytes: xored (u128) + to_be_bytes", |b| { - #[inline] - fn to_cw_bytes(value: &i32) -> Buf { - ((*value as u128 ^ i32::MIN as u128) as i32).to_be_bytes() - } - - assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!( - to_cw_bytes(&k_check.wrapping_neg()), - i32::to_cw_bytes(&k_check.wrapping_neg()) - ); - - b.iter(|| { - let k = k(); - black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&k.wrapping_neg())); - }); - }); - - group.bench_function("i32 to_cw_bytes: mut to_be_bytes + xor", |b| { - #[inline] - fn to_cw_bytes(value: &i32) -> Buf { - let mut buf = i32::to_be_bytes(*value); - buf[0] ^= 0x80; - buf - } - - assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!( - to_cw_bytes(&k_check.wrapping_neg()), - i32::to_cw_bytes(&k_check.wrapping_neg()) - ); - - b.iter(|| { - let k = k(); - black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&k.wrapping_neg())); - }); - }); - - group.bench_function("i32 to_cw_bytes: branching plus / minus", |b| { - #[inline] - fn to_cw_bytes(value: &i32) -> Buf { - if value >= &0i32 { - ((*value as u32).wrapping_sub(i32::MIN as u32)).to_be_bytes() - } else { - ((*value as u32).wrapping_add(i32::MIN as u32)).to_be_bytes() - } - } - - assert_eq!(to_cw_bytes(&0), i32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k_check), i32::to_cw_bytes(&k_check)); - assert_eq!( - to_cw_bytes(&k_check.wrapping_neg()), - i32::to_cw_bytes(&k_check.wrapping_neg()) - ); - - b.iter(|| { - let k = k(); - black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&k.wrapping_neg())); - }); - }); - - group.finish(); -} - -fn bench_unsigned_int_key(c: &mut Criterion) { - let mut group = c.benchmark_group("Unsigned int keys"); - - fn k() -> u32 { - // let k: u32 = 0x42434445; - // k - rand::thread_rng().gen_range(u32::MIN..u32::MAX) - } - // For the asserts - let k_check = k(); - - type Buf = [u8; mem::size_of::()]; - - group.bench_function("u32 to_cw_bytes", |b| { - #[inline] - fn to_cw_bytes(value: &u32) -> Buf { - value.to_be_bytes() - } - - assert_eq!(to_cw_bytes(&0), u32::to_cw_bytes(&0)); - assert_eq!(to_cw_bytes(&k_check), u32::to_cw_bytes(&k_check)); - - b.iter(|| { - let k = k(); - black_box(to_cw_bytes(&k)); - black_box(to_cw_bytes(&k)); // twice for comparability - }); - }); - - group.finish(); -} - -fn make_config() -> Criterion { - Criterion::default() - .without_plots() - .measurement_time(Duration::new(5, 0)) - .sample_size(10) - .configure_from_args() -} - -criterion_group!( - name = signed_int_key; - config = make_config(); - targets = bench_signed_int_key -); -criterion_group!( - name = unsigned_int_key; - config = make_config(); - targets = bench_unsigned_int_key -); -criterion_main!(signed_int_key, unsigned_int_key); diff --git a/packages/storage-plus/src/bound.rs b/packages/storage-plus/src/bound.rs deleted file mode 100644 index 597b569b9..000000000 --- a/packages/storage-plus/src/bound.rs +++ /dev/null @@ -1,184 +0,0 @@ -#![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/de.rs b/packages/storage-plus/src/de.rs deleted file mode 100644 index 046d8b9cb..000000000 --- a/packages/storage-plus/src/de.rs +++ /dev/null @@ -1,268 +0,0 @@ -use std::array::TryFromSliceError; -use std::convert::TryInto; - -use cosmwasm_std::{Addr, StdError, StdResult}; - -use crate::int_key::IntKey; - -pub trait KeyDeserialize { - type Output: Sized; - - fn from_vec(value: Vec) -> StdResult; - - fn from_slice(value: &[u8]) -> StdResult { - Self::from_vec(value.to_vec()) - } -} - -impl KeyDeserialize for () { - type Output = (); - - #[inline(always)] - fn from_vec(_value: Vec) -> StdResult { - Ok(()) - } -} - -impl KeyDeserialize for Vec { - type Output = Vec; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(value) - } -} - -impl KeyDeserialize for &Vec { - type Output = Vec; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(value) - } -} - -impl KeyDeserialize for &[u8] { - type Output = Vec; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(value) - } -} - -impl KeyDeserialize for String { - type Output = String; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - String::from_utf8(value).map_err(StdError::invalid_utf8) - } -} - -impl KeyDeserialize for &String { - type Output = String; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Self::Output::from_vec(value) - } -} - -impl KeyDeserialize for &str { - type Output = String; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Self::Output::from_vec(value) - } -} - -impl KeyDeserialize for Addr { - type Output = Addr; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(Addr::unchecked(String::from_vec(value)?)) - } -} - -impl KeyDeserialize for &Addr { - type Output = Addr; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Self::Output::from_vec(value) - } -} - -macro_rules! integer_de { - (for $($t:ty),+) => { - $(impl KeyDeserialize for $t { - type Output = $t; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(<$t>::from_cw_bytes(value.as_slice().try_into() - .map_err(|err: TryFromSliceError| StdError::generic_err(err.to_string()))?)) - } - })* - } -} - -integer_de!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); - -fn parse_length(value: &[u8]) -> StdResult { - Ok(u16::from_be_bytes( - value - .try_into() - .map_err(|_| StdError::generic_err("Could not read 2 byte length"))?, - ) - .into()) -} - -impl KeyDeserialize for (T, U) { - type Output = (T::Output, U::Output); - - #[inline(always)] - fn from_vec(mut value: Vec) -> StdResult { - let mut tu = value.split_off(2); - let t_len = parse_length(&value)?; - let u = tu.split_off(t_len); - - Ok((T::from_vec(tu)?, U::from_vec(u)?)) - } -} - -impl KeyDeserialize for (T, U, V) { - type Output = (T::Output, U::Output, V::Output); - - #[inline(always)] - fn from_vec(mut value: Vec) -> StdResult { - let mut tuv = value.split_off(2); - let t_len = parse_length(&value)?; - let mut len_uv = tuv.split_off(t_len); - - let mut uv = len_uv.split_off(2); - let u_len = parse_length(&len_uv)?; - let v = uv.split_off(u_len); - - Ok((T::from_vec(tuv)?, U::from_vec(uv)?, V::from_vec(v)?)) - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::PrimaryKey; - - const BYTES: &[u8] = b"Hello"; - const STRING: &str = "Hello"; - - #[test] - #[allow(clippy::unit_cmp)] - fn deserialize_empty_works() { - assert_eq!(<()>::from_slice(BYTES).unwrap(), ()); - } - - #[test] - fn deserialize_bytes_works() { - assert_eq!(>::from_slice(BYTES).unwrap(), BYTES); - assert_eq!(<&Vec>::from_slice(BYTES).unwrap(), BYTES); - assert_eq!(<&[u8]>::from_slice(BYTES).unwrap(), BYTES); - } - - #[test] - fn deserialize_string_works() { - assert_eq!(::from_slice(BYTES).unwrap(), STRING); - assert_eq!(<&String>::from_slice(BYTES).unwrap(), STRING); - assert_eq!(<&str>::from_slice(BYTES).unwrap(), STRING); - } - - #[test] - fn deserialize_broken_string_errs() { - assert!(matches!( - ::from_slice(b"\xc3").err(), - Some(StdError::InvalidUtf8 { .. }) - )); - } - - #[test] - fn deserialize_addr_works() { - assert_eq!(::from_slice(BYTES).unwrap(), Addr::unchecked(STRING)); - assert_eq!(<&Addr>::from_slice(BYTES).unwrap(), Addr::unchecked(STRING)); - } - - #[test] - fn deserialize_broken_addr_errs() { - assert!(matches!( - ::from_slice(b"\xc3").err(), - Some(StdError::InvalidUtf8 { .. }) - )); - } - - #[test] - fn deserialize_naked_integer_works() { - assert_eq!(u8::from_slice(&[1]).unwrap(), 1u8); - assert_eq!(i8::from_slice(&[127]).unwrap(), -1i8); - assert_eq!(i8::from_slice(&[128]).unwrap(), 0i8); - - assert_eq!(u16::from_slice(&[1, 0]).unwrap(), 256u16); - assert_eq!(i16::from_slice(&[128, 0]).unwrap(), 0i16); - assert_eq!(i16::from_slice(&[127, 255]).unwrap(), -1i16); - - assert_eq!(u32::from_slice(&[1, 0, 0, 0]).unwrap(), 16777216u32); - assert_eq!(i32::from_slice(&[128, 0, 0, 0]).unwrap(), 0i32); - assert_eq!(i32::from_slice(&[127, 255, 255, 255]).unwrap(), -1i32); - - assert_eq!( - u64::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 72057594037927936u64 - ); - assert_eq!(i64::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0]).unwrap(), 0i64); - assert_eq!( - i64::from_slice(&[127, 255, 255, 255, 255, 255, 255, 255]).unwrap(), - -1i64 - ); - - assert_eq!( - u128::from_slice(&[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 1329227995784915872903807060280344576u128 - ); - assert_eq!( - i128::from_slice(&[128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - 0i128 - ); - assert_eq!( - i128::from_slice(&[ - 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - -1i128 - ); - assert_eq!( - i128::from_slice(&[ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]) - .unwrap(), - 170141183460469231731687303715884105727i128, - ); - } - - #[test] - fn deserialize_tuple_works() { - assert_eq!( - <(&[u8], &str)>::from_slice((BYTES, STRING).joined_key().as_slice()).unwrap(), - (BYTES.to_vec(), STRING.to_string()) - ); - } - - #[test] - fn deserialize_triple_works() { - assert_eq!( - <(&[u8], u32, &str)>::from_slice((BYTES, 1234u32, STRING).joined_key().as_slice()) - .unwrap(), - (BYTES.to_vec(), 1234, STRING.to_string()) - ); - } -} diff --git a/packages/storage-plus/src/deque.rs b/packages/storage-plus/src/deque.rs deleted file mode 100644 index 01932a5ea..000000000 --- a/packages/storage-plus/src/deque.rs +++ /dev/null @@ -1,627 +0,0 @@ -use std::{any::type_name, convert::TryInto, marker::PhantomData}; - -use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; -use serde::{de::DeserializeOwned, Serialize}; - -use crate::helpers::{may_deserialize, namespaces_with_key}; - -// metadata keys need to have different length than the position type (4 bytes) to prevent collisions -const TAIL_KEY: &[u8] = b"t"; -const HEAD_KEY: &[u8] = b"h"; - -/// A deque stores multiple items at the given key. It provides efficient FIFO and LIFO access, -/// as well as direct index access. -/// -/// It has a maximum capacity of `u32::MAX - 1`. Make sure to never exceed that number when using this type. -/// If you do, the methods won't work as intended anymore. -pub struct Deque<'a, T> { - // prefix of the deque items - namespace: &'a [u8], - // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed - item_type: PhantomData, -} - -impl<'a, T> Deque<'a, T> { - pub const fn new(prefix: &'a str) -> Self { - Self { - namespace: prefix.as_bytes(), - item_type: PhantomData, - } - } -} - -impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { - /// Adds the given value to the end of the deque - pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { - // save value - let pos = self.tail(storage)?; - self.set_unchecked(storage, pos, value)?; - // update tail - self.set_tail(storage, pos.wrapping_add(1)); - - Ok(()) - } - - /// Adds the given value to the front of the deque - pub fn push_front(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> { - // need to subtract first, because head potentially points to existing element - let pos = self.head(storage)?.wrapping_sub(1); - self.set_unchecked(storage, pos, value)?; - // update head - self.set_head(storage, pos); - - Ok(()) - } - - /// Removes the last element of the deque and returns it - pub fn pop_back(&self, storage: &mut dyn Storage) -> StdResult> { - // get position - let pos = self.tail(storage)?.wrapping_sub(1); - let value = self.get_unchecked(storage, pos)?; - if value.is_some() { - self.remove_unchecked(storage, pos); - // only update tail if a value was popped - self.set_tail(storage, pos); - } - Ok(value) - } - - /// Removes the first element of the deque and returns it - pub fn pop_front(&self, storage: &mut dyn Storage) -> StdResult> { - // get position - let pos = self.head(storage)?; - let value = self.get_unchecked(storage, pos)?; - if value.is_some() { - self.remove_unchecked(storage, pos); - // only update head if a value was popped - self.set_head(storage, pos.wrapping_add(1)); - } - Ok(value) - } - - /// Returns the first element of the deque without removing it - pub fn front(&self, storage: &dyn Storage) -> StdResult> { - let pos = self.head(storage)?; - self.get_unchecked(storage, pos) - } - - /// Returns the first element of the deque without removing it - pub fn back(&self, storage: &dyn Storage) -> StdResult> { - let pos = self.tail(storage)?.wrapping_sub(1); - self.get_unchecked(storage, pos) - } - - /// Gets the length of the deque. - #[allow(clippy::len_without_is_empty)] - pub fn len(&self, storage: &dyn Storage) -> StdResult { - Ok(calc_len(self.head(storage)?, self.tail(storage)?)) - } - - /// Returns `true` if the deque contains no elements. - pub fn is_empty(&self, storage: &dyn Storage) -> StdResult { - Ok(self.len(storage)? == 0) - } - - /// Gets the head position from storage. - /// - /// Unless the deque is empty, this points to the first element. - #[inline] - fn head(&self, storage: &dyn Storage) -> StdResult { - self.read_meta_key(storage, HEAD_KEY) - } - - /// Gets the tail position from storage. - /// - /// This points to the first empty position after the last element. - #[inline] - fn tail(&self, storage: &dyn Storage) -> StdResult { - self.read_meta_key(storage, TAIL_KEY) - } - - #[inline] - fn set_head(&self, storage: &mut dyn Storage, value: u32) { - self.set_meta_key(storage, HEAD_KEY, value); - } - - #[inline] - fn set_tail(&self, storage: &mut dyn Storage, value: u32) { - self.set_meta_key(storage, TAIL_KEY, value); - } - - /// Helper method for `tail` and `head` methods to handle reading the value from storage - fn read_meta_key(&self, storage: &dyn Storage, key: &[u8]) -> StdResult { - let full_key = namespaces_with_key(&[self.namespace], key); - storage - .get(&full_key) - .map(|vec| { - Ok(u32::from_be_bytes( - vec.as_slice() - .try_into() - .map_err(|e| StdError::parse_err("u32", e))?, - )) - }) - .unwrap_or(Ok(0)) - } - - /// Helper method for `set_tail` and `set_head` methods to write to storage - #[inline] - fn set_meta_key(&self, storage: &mut dyn Storage, key: &[u8], value: u32) { - let full_key = namespaces_with_key(&[self.namespace], key); - storage.set(&full_key, &value.to_be_bytes()); - } - - /// Returns the value at the given position in the queue or `None` if the index is out of bounds - pub fn get(&self, storage: &dyn Storage, pos: u32) -> StdResult> { - let head = self.head(storage)?; - let tail = self.tail(storage)?; - - if pos >= calc_len(head, tail) { - // out of bounds - return Ok(None); - } - - let pos = head.wrapping_add(pos); - self.get_unchecked(storage, pos) - .and_then(|v| v.ok_or_else(|| StdError::not_found(format!("deque position {}", pos)))) - .map(Some) - } - - /// Tries to get the value at the given position - /// Used internally - fn get_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult> { - let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); - may_deserialize(&storage.get(&prefixed_key)) - } - - /// Removes the value at the given position - /// Used internally - fn remove_unchecked(&self, storage: &mut dyn Storage, pos: u32) { - let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); - storage.remove(&prefixed_key); - } - - /// Tries to set the value at the given position - /// Used internally when pushing - fn set_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> { - let prefixed_key = namespaces_with_key(&[self.namespace], &pos.to_be_bytes()); - storage.set(&prefixed_key, &to_vec(value)?); - - Ok(()) - } -} - -// used internally to avoid additional storage loads -#[inline] -fn calc_len(head: u32, tail: u32) -> u32 { - tail.wrapping_sub(head) -} - -impl<'a, T: Serialize + DeserializeOwned> Deque<'a, T> { - pub fn iter(&self, storage: &'a dyn Storage) -> StdResult> { - Ok(DequeIter { - deque: self, - storage, - start: self.head(storage)?, - end: self.tail(storage)?, - }) - } -} - -pub struct DequeIter<'a, T> -where - T: Serialize + DeserializeOwned, -{ - deque: &'a Deque<'a, T>, - storage: &'a dyn Storage, - start: u32, - end: u32, -} - -impl<'a, T> Iterator for DequeIter<'a, T> -where - T: Serialize + DeserializeOwned, -{ - type Item = StdResult; - - fn next(&mut self) -> Option { - if self.start == self.end { - return None; - } - - let item = self - .deque - .get_unchecked(self.storage, self.start) - .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); - self.start = self.start.wrapping_add(1); - - Some(item) - } - - fn size_hint(&self) -> (usize, Option) { - let len = calc_len(self.start, self.end) as usize; - (len, Some(len)) - } - - // The default implementation calls `next` repeatedly, which is very costly in our case. - // It is used when skipping over items, so this allows cheap skipping. - // - // Once `advance_by` is stabilized, we can implement that instead (`nth` calls it internally). - fn nth(&mut self, n: usize) -> Option { - // make sure that we don't skip past the end - if calc_len(self.start, self.end) < n as u32 { - // mark as empty - self.start = self.end; - } else { - self.start = self.start.wrapping_add(n as u32); - } - self.next() - } -} - -impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> -where - T: Serialize + DeserializeOwned, -{ - fn next_back(&mut self) -> Option { - if self.start == self.end { - return None; - } - - let item = self - .deque - .get_unchecked(self.storage, self.end.wrapping_sub(1)) // end points to position after last element - .and_then(|item| item.ok_or_else(|| StdError::not_found(type_name::()))); - self.end = self.end.wrapping_sub(1); - - Some(item) - } - - // see [`DequeIter::nth`] - fn nth_back(&mut self, n: usize) -> Option { - // make sure that we don't skip past the start - if calc_len(self.start, self.end) < n as u32 { - // mark as empty - self.end = self.start; - } else { - self.end = self.end.wrapping_sub(n as u32); - } - self.next_back() - } -} -#[cfg(test)] -mod tests { - use crate::deque::Deque; - - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::{StdError, StdResult}; - use serde::{Deserialize, Serialize}; - - #[test] - fn push_and_pop() { - const PEOPLE: Deque = Deque::new("people"); - let mut store = MockStorage::new(); - - // push some entries - PEOPLE.push_back(&mut store, &"jack".to_owned()).unwrap(); - PEOPLE.push_back(&mut store, &"john".to_owned()).unwrap(); - PEOPLE.push_back(&mut store, &"joanne".to_owned()).unwrap(); - - // pop them, should be in correct order - assert_eq!("jack", PEOPLE.pop_front(&mut store).unwrap().unwrap()); - assert_eq!("john", PEOPLE.pop_front(&mut store).unwrap().unwrap()); - - // push again in-between - PEOPLE.push_back(&mut store, &"jason".to_owned()).unwrap(); - - // pop last person from first batch - assert_eq!("joanne", PEOPLE.pop_front(&mut store).unwrap().unwrap()); - - // pop the entry pushed in-between - assert_eq!("jason", PEOPLE.pop_front(&mut store).unwrap().unwrap()); - - // nothing after that - assert_eq!(None, PEOPLE.pop_front(&mut store).unwrap()); - - // now push to the front - PEOPLE.push_front(&mut store, &"pascal".to_owned()).unwrap(); - PEOPLE.push_front(&mut store, &"peter".to_owned()).unwrap(); - PEOPLE.push_front(&mut store, &"paul".to_owned()).unwrap(); - - assert_eq!("pascal", PEOPLE.pop_back(&mut store).unwrap().unwrap()); - assert_eq!("paul", PEOPLE.pop_front(&mut store).unwrap().unwrap()); - assert_eq!("peter", PEOPLE.pop_back(&mut store).unwrap().unwrap()); - } - - #[test] - fn length() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - assert_eq!(deque.len(&store).unwrap(), 0); - assert!(deque.is_empty(&store).unwrap()); - - // push some entries - deque.push_front(&mut store, &1234).unwrap(); - deque.push_back(&mut store, &2345).unwrap(); - deque.push_front(&mut store, &3456).unwrap(); - deque.push_back(&mut store, &4567).unwrap(); - assert_eq!(deque.len(&store).unwrap(), 4); - assert!(!deque.is_empty(&store).unwrap()); - - // pop some - deque.pop_front(&mut store).unwrap(); - deque.pop_back(&mut store).unwrap(); - deque.pop_front(&mut store).unwrap(); - assert_eq!(deque.len(&store).unwrap(), 1); - assert!(!deque.is_empty(&store).unwrap()); - - // pop the last one - deque.pop_front(&mut store).unwrap(); - assert_eq!(deque.len(&store).unwrap(), 0); - assert!(deque.is_empty(&store).unwrap()); - - // should stay 0 after that - assert_eq!(deque.pop_back(&mut store).unwrap(), None); - assert_eq!( - deque.len(&store).unwrap(), - 0, - "popping from empty deque should keep length 0" - ); - assert!(deque.is_empty(&store).unwrap()); - } - - #[test] - fn iterator() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - // push some items - deque.push_back(&mut store, &1).unwrap(); - deque.push_back(&mut store, &2).unwrap(); - deque.push_back(&mut store, &3).unwrap(); - deque.push_back(&mut store, &4).unwrap(); - - let items: StdResult> = deque.iter(&store).unwrap().collect(); - assert_eq!(items.unwrap(), [1, 2, 3, 4]); - - // nth should work correctly - let mut iter = deque.iter(&store).unwrap(); - assert_eq!(iter.nth(6), None); - assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); - assert_eq!(iter.next(), None); - - let mut iter = deque.iter(&store).unwrap(); - assert_eq!(iter.nth(1).unwrap().unwrap(), 2); - assert_eq!(iter.next().unwrap().unwrap(), 3); - } - - #[test] - fn reverse_iterator() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - // push some items - deque.push_back(&mut store, &1).unwrap(); - deque.push_back(&mut store, &2).unwrap(); - deque.push_back(&mut store, &3).unwrap(); - deque.push_back(&mut store, &4).unwrap(); - - let items: StdResult> = deque.iter(&store).unwrap().rev().collect(); - assert_eq!(items.unwrap(), [4, 3, 2, 1]); - - // nth should work correctly - let mut iter = deque.iter(&store).unwrap(); - assert_eq!(iter.nth_back(6), None); - assert_eq!(iter.start, iter.end, "iter should detect skipping too far"); - assert_eq!(iter.next_back(), None); - - let mut iter = deque.iter(&store).unwrap().rev(); - assert_eq!(iter.nth(1).unwrap().unwrap(), 3); - assert_eq!(iter.next().unwrap().unwrap(), 2); - - // mixed - let mut iter = deque.iter(&store).unwrap(); - assert_eq!(iter.next().unwrap().unwrap(), 1); - assert_eq!(iter.next_back().unwrap().unwrap(), 4); - assert_eq!(iter.next_back().unwrap().unwrap(), 3); - assert_eq!(iter.next().unwrap().unwrap(), 2); - assert_eq!(iter.next(), None); - assert_eq!(iter.next_back(), None); - } - - #[test] - fn wrapping() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - // simulate deque that was pushed and popped `u32::MAX` times - deque.set_head(&mut store, u32::MAX); - deque.set_tail(&mut store, u32::MAX); - - // should be empty - assert_eq!(deque.pop_front(&mut store).unwrap(), None); - assert_eq!(deque.len(&store).unwrap(), 0); - - // pushing should still work - deque.push_back(&mut store, &1).unwrap(); - assert_eq!( - deque.len(&store).unwrap(), - 1, - "length should calculate correctly, even when wrapping" - ); - assert_eq!( - deque.pop_front(&mut store).unwrap(), - Some(1), - "popping should work, even when wrapping" - ); - } - - #[test] - fn wrapping_iterator() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - deque.set_head(&mut store, u32::MAX); - deque.set_tail(&mut store, u32::MAX); - - deque.push_back(&mut store, &1).unwrap(); - deque.push_back(&mut store, &2).unwrap(); - deque.push_back(&mut store, &3).unwrap(); - deque.push_back(&mut store, &4).unwrap(); - deque.push_back(&mut store, &5).unwrap(); - - let mut iter = deque.iter(&store).unwrap(); - assert_eq!(iter.next().unwrap().unwrap(), 1); - assert_eq!(iter.next().unwrap().unwrap(), 2); - assert_eq!(iter.next_back().unwrap().unwrap(), 5); - assert_eq!(iter.nth(1).unwrap().unwrap(), 4); - assert_eq!(iter.nth(1), None); - assert_eq!(iter.start, iter.end); - } - - #[test] - fn front_back() { - let deque: Deque = Deque::new("test"); - let mut store = MockStorage::new(); - - assert_eq!(deque.back(&store).unwrap(), None); - deque.push_back(&mut store, &1).unwrap(); - assert_eq!(deque.back(&store).unwrap(), Some(1)); - assert_eq!(deque.front(&store).unwrap(), Some(1)); - deque.push_back(&mut store, &2).unwrap(); - assert_eq!(deque.back(&store).unwrap(), Some(2)); - assert_eq!(deque.front(&store).unwrap(), Some(1)); - deque.push_front(&mut store, &3).unwrap(); - assert_eq!(deque.back(&store).unwrap(), Some(2)); - assert_eq!(deque.front(&store).unwrap(), Some(3)); - } - - #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] - struct Data { - pub name: String, - pub age: i32, - } - - const DATA: Deque = Deque::new("data"); - - #[test] - fn readme_works() -> StdResult<()> { - let mut store = MockStorage::new(); - - // read methods return a wrapped Option, so None if the deque is empty - let empty = DATA.front(&store)?; - assert_eq!(None, empty); - - // some example entries - let p1 = Data { - name: "admin".to_string(), - age: 1234, - }; - let p2 = Data { - name: "user".to_string(), - age: 123, - }; - - // use it like a queue by pushing and popping at opposite ends - DATA.push_back(&mut store, &p1)?; - DATA.push_back(&mut store, &p2)?; - - let admin = DATA.pop_front(&mut store)?; - assert_eq!(admin.as_ref(), Some(&p1)); - let user = DATA.pop_front(&mut store)?; - assert_eq!(user.as_ref(), Some(&p2)); - - // or push and pop at the same end to use it as a stack - DATA.push_back(&mut store, &p1)?; - DATA.push_back(&mut store, &p2)?; - - let user = DATA.pop_back(&mut store)?; - assert_eq!(user.as_ref(), Some(&p2)); - let admin = DATA.pop_back(&mut store)?; - assert_eq!(admin.as_ref(), Some(&p1)); - - // you can also iterate over it - DATA.push_front(&mut store, &p1)?; - DATA.push_front(&mut store, &p2)?; - - let all: StdResult> = DATA.iter(&store)?.collect(); - assert_eq!(all?, [p2.clone(), p1.clone()]); - - // or access an index directly - assert_eq!(DATA.get(&store, 0)?, Some(p2)); - assert_eq!(DATA.get(&store, 1)?, Some(p1)); - assert_eq!(DATA.get(&store, 3)?, None); - - Ok(()) - } - - #[test] - fn iterator_errors_when_item_missing() { - let mut store = MockStorage::new(); - - let deque = Deque::new("error_test"); - - deque.push_back(&mut store, &1u32).unwrap(); - // manually remove it - deque.remove_unchecked(&mut store, 0); - - let mut iter = deque.iter(&store).unwrap(); - - assert!( - matches!(iter.next(), Some(Err(StdError::NotFound { .. }))), - "iterator should error when item is missing" - ); - - let mut iter = deque.iter(&store).unwrap().rev(); - - assert!( - matches!(iter.next(), Some(Err(StdError::NotFound { .. }))), - "reverse iterator should error when item is missing" - ); - } - - #[test] - fn get() { - let mut store = MockStorage::new(); - - let deque = Deque::new("test"); - - deque.push_back(&mut store, &1u32).unwrap(); - deque.push_back(&mut store, &2).unwrap(); - - assert_eq!(deque.get(&store, 0).unwrap(), Some(1)); - assert_eq!(deque.get(&store, 1).unwrap(), Some(2)); - assert_eq!( - deque.get(&store, 2).unwrap(), - None, - "out of bounds access should return None" - ); - - // manually remove storage item - deque.remove_unchecked(&mut store, 1); - - assert!( - matches!(deque.get(&store, 1), Err(StdError::NotFound { .. })), - "missing deque item should error" - ); - - // start fresh - let deque = Deque::new("test2"); - - deque.push_back(&mut store, &0u32).unwrap(); - deque.push_back(&mut store, &1).unwrap(); - // push to front to move the head index - deque.push_front(&mut store, &u32::MAX).unwrap(); - deque.push_front(&mut store, &(u32::MAX - 1)).unwrap(); - - assert_eq!(deque.get(&store, 0).unwrap().unwrap(), u32::MAX - 1); - assert_eq!(deque.get(&store, 1).unwrap().unwrap(), u32::MAX); - assert_eq!(deque.get(&store, 2).unwrap().unwrap(), 0); - assert_eq!(deque.get(&store, 3).unwrap().unwrap(), 1); - assert_eq!( - deque.get(&store, 5).unwrap(), - None, - "out of bounds access should return None" - ); - } -} diff --git a/packages/storage-plus/src/endian.rs b/packages/storage-plus/src/endian.rs deleted file mode 100644 index eeab87845..000000000 --- a/packages/storage-plus/src/endian.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! This code is inspired by (and partially borrowed from) -//! https://docs.rs/endiannezz/0.5.2/endiannezz/trait.Primitive.html -//! but there was a lot in that crate I did not want, the name did not inspire -//! confidence, and I wanted a different return value, so I just took the code -//! to modify slightly. - -// TODO: figure out these macros and let us replace (self: Self) with self -#![allow(clippy::needless_arbitrary_self_type)] - -use std::mem; - -pub trait Endian: Sized + Copy { - type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; - - fn to_le_bytes(self) -> Self::Buf; - fn to_be_bytes(self) -> Self::Buf; - - fn from_le_bytes(bytes: Self::Buf) -> Self; - fn from_be_bytes(bytes: Self::Buf) -> Self; -} - -macro_rules! delegate { - ($ty:ty, [$($method:ident),* $(,)?], ($param:ident : $param_ty:ty) -> $ret:ty) => { - delegate!(@inner $ty, [$($method),*], $param, $param_ty, $ret); - }; - (@inner $ty:ty, [$($method:ident),*], $param:ident, $param_ty:ty, $ret:ty) => { - $( - #[inline] - fn $method ($param: $param_ty) -> $ret { <$ty>::$method($param) } - )* - }; -} - -macro_rules! impl_primitives { - ($($ty:ty),* $(,)?) => { - $( - impl Endian for $ty { - type Buf = [u8; mem::size_of::<$ty>()]; - - delegate!($ty, [ - to_le_bytes, - to_be_bytes, - ], (self: Self) -> Self::Buf); - - delegate!($ty, [ - from_le_bytes, - from_be_bytes, - ], (bytes: Self::Buf) -> Self); - } - )* - }; -} - -#[rustfmt::skip] -impl_primitives![ - i8, i16, i32, i64, i128, - u8, u16, u32, u64, u128, -]; diff --git a/packages/storage-plus/src/helpers.rs b/packages/storage-plus/src/helpers.rs deleted file mode 100644 index 701b014fe..000000000 --- a/packages/storage-plus/src/helpers.rs +++ /dev/null @@ -1,194 +0,0 @@ -//! This module is an implemention of a namespacing scheme described -//! in https://github.com/webmaster128/key-namespacing#length-prefixed-keys -//! -//! Everything in this file is only responsible for building such keys -//! and is in no way specific to any kind of storage. - -use serde::de::DeserializeOwned; -use std::any::type_name; - -use crate::keys::Key; - -use cosmwasm_std::{ - from_slice, to_vec, Addr, Binary, ContractResult, CustomQuery, QuerierWrapper, QueryRequest, - StdError, StdResult, SystemResult, WasmQuery, -}; - -/// may_deserialize parses json bytes from storage (Option), returning Ok(None) if no data present -/// -/// value is an odd type, but this is meant to be easy to use with output from storage.get (Option>) -/// and value.map(|s| s.as_slice()) seems trickier than &value -pub(crate) fn may_deserialize( - value: &Option>, -) -> StdResult> { - match value { - Some(vec) => Ok(Some(from_slice(vec)?)), - None => Ok(None), - } -} - -/// must_deserialize parses json bytes from storage (Option), returning NotFound error if no data present -pub(crate) fn must_deserialize(value: &Option>) -> StdResult { - match value { - Some(vec) => from_slice(vec), - None => Err(StdError::not_found(type_name::())), - } -} - -/// This is equivalent concat(to_length_prefixed_nested(namespaces), key) -/// But more efficient when the intermediate namespaces often must be recalculated -pub(crate) fn namespaces_with_key(namespaces: &[&[u8]], key: &[u8]) -> Vec { - let mut size = key.len(); - for &namespace in namespaces { - size += namespace.len() + 2; - } - - let mut out = Vec::with_capacity(size); - for &namespace in namespaces { - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - } - out.extend_from_slice(key); - out -} - -/// Customization of namespaces_with_key for when -/// there are multiple sets we do not want to combine just to call this -pub(crate) fn nested_namespaces_with_key( - top_names: &[&[u8]], - sub_names: &[Key], - key: &[u8], -) -> Vec { - let mut size = key.len(); - for &namespace in top_names { - size += namespace.len() + 2; - } - for namespace in sub_names { - size += namespace.as_ref().len() + 2; - } - - let mut out = Vec::with_capacity(size); - for &namespace in top_names { - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - } - for namespace in sub_names { - out.extend_from_slice(&encode_length(namespace.as_ref())); - out.extend_from_slice(namespace.as_ref()); - } - out.extend_from_slice(key); - out -} - -/// Encodes the length of a given namespace as a 2 byte big endian encoded integer -pub(crate) fn encode_length(namespace: &[u8]) -> [u8; 2] { - if namespace.len() > 0xFFFF { - panic!("only supports namespaces up to length 0xFFFF") - } - let length_bytes = (namespace.len() as u32).to_be_bytes(); - [length_bytes[2], length_bytes[3]] -} - -/// Use this in Map/SnapshotMap/etc when you want to provide a QueryRaw helper. -/// This is similar to querier.query(WasmQuery::Raw{}), except it does NOT parse the -/// result, but return a possibly empty Binary to be handled by the calling code. -/// That is essential to handle b"" as None. -pub(crate) fn query_raw( - querier: &QuerierWrapper, - contract_addr: Addr, - key: Binary, -) -> StdResult { - let request: QueryRequest = WasmQuery::Raw { - contract_addr: contract_addr.into(), - key, - } - .into(); - - let raw = to_vec(&request).map_err(|serialize_err| { - StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err)) - })?; - match querier.raw_query(&raw) { - SystemResult::Err(system_err) => Err(StdError::generic_err(format!( - "Querier system error: {}", - system_err - ))), - SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(format!( - "Querier contract error: {}", - contract_err - ))), - SystemResult::Ok(ContractResult::Ok(value)) => Ok(value), - } -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::{to_vec, StdError}; - use serde::{Deserialize, Serialize}; - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Person { - pub name: String, - pub age: i32, - } - - #[test] - fn encode_length_works() { - assert_eq!(encode_length(b""), *b"\x00\x00"); - assert_eq!(encode_length(b"a"), *b"\x00\x01"); - assert_eq!(encode_length(b"aa"), *b"\x00\x02"); - assert_eq!(encode_length(b"aaa"), *b"\x00\x03"); - assert_eq!(encode_length(&vec![1; 255]), *b"\x00\xff"); - assert_eq!(encode_length(&vec![1; 256]), *b"\x01\x00"); - assert_eq!(encode_length(&vec![1; 12345]), *b"\x30\x39"); - assert_eq!(encode_length(&vec![1; 65535]), *b"\xff\xff"); - } - - #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] - fn encode_length_panics_for_large_values() { - encode_length(&vec![1; 65536]); - } - - #[test] - fn may_deserialize_handles_some() { - let person = Person { - name: "Maria".to_string(), - age: 42, - }; - let value = to_vec(&person).unwrap(); - - let may_parse: Option = may_deserialize(&Some(value)).unwrap(); - assert_eq!(may_parse, Some(person)); - } - - #[test] - fn may_deserialize_handles_none() { - let may_parse = may_deserialize::(&None).unwrap(); - assert_eq!(may_parse, None); - } - - #[test] - fn must_deserialize_handles_some() { - let person = Person { - name: "Maria".to_string(), - age: 42, - }; - let value = to_vec(&person).unwrap(); - let loaded = Some(value); - - let parsed: Person = must_deserialize(&loaded).unwrap(); - assert_eq!(parsed, person); - } - - #[test] - fn must_deserialize_handles_none() { - let parsed = must_deserialize::(&None); - match parsed.unwrap_err() { - StdError::NotFound { kind, .. } => { - assert_eq!(kind, "cw_storage_plus::helpers::test::Person") - } - e => panic!("Unexpected error {}", e), - } - } -} diff --git a/packages/storage-plus/src/indexed_map.rs b/packages/storage-plus/src/indexed_map.rs deleted file mode 100644 index 4ea2e4e27..000000000 --- a/packages/storage-plus/src/indexed_map.rs +++ /dev/null @@ -1,1735 +0,0 @@ -// 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; - -use crate::de::KeyDeserialize; -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}; -use crate::{Bound, Path}; - -pub trait IndexList { - fn get_indexes(&'_ self) -> Box> + '_>; -} - -// TODO: remove traits here and make this const fn new -/// `IndexedMap` works like a `Map` but has a secondary index -pub struct IndexedMap<'a, K, T, I> -where - K: PrimaryKey<'a>, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - pk_namespace: &'a [u8], - primary: Map<'a, K, T>, - /// This is meant to be read directly to get the proper types, like: - /// map.idx.owner.items(...) - pub idx: I, -} - -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - K: PrimaryKey<'a>, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - // TODO: remove traits here and make this const fn new - pub fn new(pk_namespace: &'a str, indexes: I) -> Self { - IndexedMap { - pk_namespace: pk_namespace.as_bytes(), - primary: Map::new(pk_namespace), - idx: indexes, - } - } - - pub fn key(&self, k: K) -> Path { - self.primary.key(k) - } -} - -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - K: PrimaryKey<'a>, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - /// save will serialize the model and store, returns an error on serialization issues. - /// this must load the old value to update the indexes properly - /// if you loaded the old value earlier in the same function, use replace to avoid needless db reads - pub fn save(&self, store: &mut dyn Storage, key: K, data: &T) -> StdResult<()> { - let old_data = self.may_load(store, key.clone())?; - self.replace(store, key, Some(data), old_data.as_ref()) - } - - pub fn remove(&self, store: &mut dyn Storage, key: K) -> StdResult<()> { - let old_data = self.may_load(store, key.clone())?; - self.replace(store, key, None, old_data.as_ref()) - } - - /// replace writes data to key. old_data must be the current stored value (from a previous load) - /// and is used to properly update the index. This is used by save, replace, and update - /// and can be called directly if you want to optimize - pub fn replace( - &self, - store: &mut dyn Storage, - key: K, - data: Option<&T>, - old_data: Option<&T>, - ) -> StdResult<()> { - // this is the key *relative* to the primary map namespace - let pk = key.joined_key(); - if let Some(old) = old_data { - for index in self.idx.get_indexes() { - index.remove(store, &pk, old)?; - } - } - if let Some(updated) = data { - for index in self.idx.get_indexes() { - index.save(store, &pk, updated)?; - } - self.primary.save(store, key, updated)?; - } else { - self.primary.remove(store, key); - } - Ok(()) - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - pub fn update(&self, store: &mut dyn Storage, key: K, action: A) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - let input = self.may_load(store, key.clone())?; - let old_val = input.clone(); - let output = action(input)?; - self.replace(store, key, Some(&output), old_val.as_ref())?; - Ok(output) - } - - // Everything else, that doesn't touch indexers, is just pass-through from self.core, - // thus can be used from while iterating over indexes - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage, key: K) -> StdResult { - self.primary.load(store, key) - } - - /// may_load will parse the data stored at the key if present, returns Ok(None) if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage, key: K) -> StdResult> { - self.primary.may_load(store, key) - } - - /// Returns true if storage contains this key, without parsing or interpreting the contents. - pub fn has(&self, store: &dyn Storage, k: K) -> bool { - self.primary.key(k).has(store) - } - - // use no_prefix to scan -> range - fn no_prefix_raw(&self) -> Prefix, T, K> { - Prefix::new(self.pk_namespace, &[]) - } - - /// Clears the map, removing all elements. - pub fn clear(&self, store: &mut dyn Storage) { - const TAKE: usize = 10; - let mut cleared = false; - - while !cleared { - let paths = self - .no_prefix_raw() - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .map(|raw_key| Path::::new(self.pk_namespace, &[raw_key.as_slice()])) - // Take just TAKE elements to prevent possible heap overflow if the Map is big. - .take(TAKE) - .collect::>(); - - paths.iter().for_each(|path| store.remove(path)); - - cleared = paths.len() < TAKE; - } - } - - /// Returns `true` if the map is empty. - pub fn is_empty(&self, store: &dyn Storage) -> bool { - self.no_prefix_raw() - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .next() - .is_none() - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - K: PrimaryKey<'a>, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the `Prefix` - /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box>> + 'c> - where - T: 'c, - 'a: 'c, - { - let mapped = - namespaced_prefix_range(store, self.pk_namespace, min, max, order).map(deserialize_v); - Box::new(mapped) - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a>, - I: IndexList, -{ - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { - Prefix::new(self.pk_namespace, &p.prefix()) - } - - pub fn prefix(&self, p: K::Prefix) -> Prefix { - Prefix::new(self.pk_namespace, &p.prefix()) - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T, I> IndexedMap<'a, K, T, I> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + KeyDeserialize, - I: IndexList, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - K: 'c, - K::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.pk_namespace, min, max, order) - .map(deserialize_kv::); - 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>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - K::Output: 'static, - { - self.no_prefix().range(store, min, max, order) - } - - pub fn keys<'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().keys(store, min, max, order) - } - - fn no_prefix(&self) -> Prefix { - Prefix::new(self.pk_namespace, &[]) - } -} - -#[cfg(test)] -mod test { - use super::*; - - use crate::indexes::test::{index_string_tuple, index_tuple}; - use crate::{MultiIndex, UniqueIndex}; - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::{MemoryStorage, Order}; - use serde::{Deserialize, Serialize}; - - #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] - struct Data { - pub name: String, - pub last_name: String, - pub age: u32, - } - - struct DataIndexes<'a> { - // Last type parameters are for signaling pk deserialization - pub name: MultiIndex<'a, String, Data, String>, - pub age: UniqueIndex<'a, u32, Data, String>, - pub name_lastname: UniqueIndex<'a, (Vec, Vec), Data, String>, - } - - // Future Note: this can likely be macro-derived - impl<'a> IndexList for DataIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.name, &self.age, &self.name_lastname]; - Box::new(v.into_iter()) - } - } - - // For composite multi index tests - struct DataCompositeMultiIndex<'a> { - // Last type parameter is for signaling pk deserialization - pub name_age: MultiIndex<'a, (Vec, u32), Data, String>, - } - - // Future Note: this can likely be macro-derived - impl<'a> IndexList for DataCompositeMultiIndex<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.name_age]; - Box::new(v.into_iter()) - } - } - - // Can we make it easier to define this? (less wordy generic) - fn build_map<'a>() -> IndexedMap<'a, &'a str, Data, DataIndexes<'a>> { - let indexes = DataIndexes { - name: MultiIndex::new(|_pk, d| d.name.clone(), "data", "data__name"), - age: UniqueIndex::new(|d| d.age, "data__age"), - name_lastname: UniqueIndex::new( - |d| index_string_tuple(&d.name, &d.last_name), - "data__name_lastname", - ), - }; - IndexedMap::new("data", indexes) - } - - fn save_data<'a>( - store: &mut MockStorage, - map: &IndexedMap<'a, &'a str, Data, DataIndexes<'a>>, - ) -> (Vec<&'a str>, Vec) { - let mut pks = vec![]; - let mut datas = vec![]; - let data = Data { - name: "Maria".to_string(), - last_name: "Doe".to_string(), - age: 42, - }; - let pk = "1"; - map.save(store, pk, &data).unwrap(); - pks.push(pk); - datas.push(data); - - // same name (multi-index), different last name, different age => ok - let data = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 23, - }; - let pk = "2"; - map.save(store, pk, &data).unwrap(); - pks.push(pk); - datas.push(data); - - // different name, different last name, different age => ok - let data = Data { - name: "John".to_string(), - last_name: "Wayne".to_string(), - age: 32, - }; - let pk = "3"; - map.save(store, pk, &data).unwrap(); - pks.push(pk); - datas.push(data); - - let data = Data { - name: "Maria Luisa".to_string(), - last_name: "Rodriguez".to_string(), - age: 12, - }; - let pk = "4"; - map.save(store, pk, &data).unwrap(); - pks.push(pk); - datas.push(data); - - let data = Data { - name: "Marta".to_string(), - last_name: "After".to_string(), - age: 90, - }; - let pk = "5"; - map.save(store, pk, &data).unwrap(); - pks.push(pk); - datas.push(data); - - (pks, datas) - } - - #[test] - fn store_and_load_by_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - let pk = pks[0]; - let data = &datas[0]; - - // load it properly - let loaded = map.load(&store, pk).unwrap(); - assert_eq!(*data, loaded); - - let count = map - .idx - .name - .prefix("Maria".to_string()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(2, count); - - // load it by secondary index - let marias: Vec<_> = map - .idx - .name - .prefix("Maria".to_string()) - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - assert_eq!(2, marias.len()); - let (k, v) = &marias[0]; - assert_eq!(pk, String::from_slice(k).unwrap()); - assert_eq!(data, v); - - // other index doesn't match (1 byte after) - let count = map - .idx - .name - .prefix("Marib".to_string()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // other index doesn't match (1 byte before) - let count = map - .idx - .name - .prefix("Mari`".to_string()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // other index doesn't match (longer) - let count = map - .idx - .name - .prefix("Maria5".to_string()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // 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 marias = map - .idx - .name - .range_raw(&store, Some(Bound::inclusive(key)), None, Order::Ascending) - .collect::>>() - .unwrap(); - // gets from the first "Maria" until the end - assert_eq!(4, marias.len()); - - // This is equivalent to using prefix_range - let key = "Maria".to_string(); - let marias2 = map - .idx - .name - .prefix_range_raw( - &store, - Some(PrefixBound::inclusive(key)), - None, - Order::Ascending, - ) - .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()); - // Iterate using a (exclusive) bound over the key. - // (Useful for pagination / continuation contexts). - let count = map - .idx - .name - .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 key. - let count = map - .idx - .age - .range_raw( - &store, - Some(Bound::inclusive(age_key)), - None, - Order::Ascending, - ) - .count(); - // gets all the greater than or equal to 23 years old people - assert_eq!(4, count); - - // match on proper age - let proper = 42u32; - let aged = map.idx.age.item(&store, proper).unwrap().unwrap(); - assert_eq!(pk, String::from_vec(aged.0).unwrap()); - assert_eq!(*data, aged.1); - - // no match on wrong age - let too_old = 43u32; - let aged = map.idx.age.item(&store, too_old).unwrap(); - assert_eq!(None, aged); - } - - #[test] - fn existence() { - let mut store = MockStorage::new(); - let map = build_map(); - let (pks, _) = save_data(&mut store, &map); - - assert!(map.has(&store, pks[0])); - assert!(!map.has(&store, "6")); - } - - #[test] - fn range_raw_simple_key_by_multi_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk = "5627"; - map.save(&mut store, pk, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk = "5628"; - map.save(&mut store, pk, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 24, - }; - let pk = "5629"; - map.save(&mut store, pk, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 12, - }; - let pk = "5630"; - map.save(&mut store, pk, &data4).unwrap(); - - let marias: Vec<_> = map - .idx - .name - .prefix("Maria".to_string()) - .range_raw(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks, sorted by (descending) pk - assert_eq!(marias[0].0, b"5629"); - assert_eq!(marias[1].0, b"5627"); - // Data is correct - assert_eq!(marias[0].1, data3); - assert_eq!(marias[1].1, data1); - } - - #[test] - fn range_simple_key_by_multi_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk = "5627"; - map.save(&mut store, pk, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk = "5628"; - map.save(&mut store, pk, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 24, - }; - let pk = "5629"; - map.save(&mut store, pk, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 12, - }; - let pk = "5630"; - map.save(&mut store, pk, &data4).unwrap(); - - let marias: Vec<_> = map - .idx - .name - .prefix("Maria".to_string()) - .range(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks, sorted by (descending) pk - assert_eq!(marias[0].0, "5629"); - assert_eq!(marias[1].0, "5627"); - // Data is correct - assert_eq!(marias[0].1, data3); - assert_eq!(marias[1].1, data1); - } - - #[test] - fn range_raw_composite_key_by_multi_index() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1: &[u8] = b"5627"; - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2: &[u8] = b"5628"; - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3: &[u8] = b"5629"; - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4: &[u8] = b"5630"; - map.save(&mut store, pk4, &data4).unwrap(); - - let marias: Vec<_> = map - .idx - .name_age - .sub_prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks, sorted by (descending) age - assert_eq!(pk1, marias[0].0); - assert_eq!(pk3, marias[1].0); - - // Data - assert_eq!(data1, marias[0].1); - assert_eq!(data3, marias[1].1); - } - - #[test] - fn range_composite_key_by_multi_index() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = "5627"; - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = "5628"; - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = "5629"; - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = "5630"; - map.save(&mut store, pk4, &data4).unwrap(); - - let marias: Vec<_> = map - .idx - .name_age - .sub_prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks, sorted by (descending) age - assert_eq!(pk1, marias[0].0); - assert_eq!(pk3, marias[1].0); - - // Data - assert_eq!(data1, marias[0].1); - assert_eq!(data3, marias[1].1); - } - - #[test] - fn unique_index_enforced() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // different name, different last name, same age => error - let data5 = Data { - name: "Marcel".to_string(), - last_name: "Laurens".to_string(), - age: 42, - }; - let pk5 = "4"; - - // enforce this returns some error - map.save(&mut store, pk5, &data5).unwrap_err(); - - // query by unique key - // match on proper age - let age42 = 42u32; - let (k, v) = map.idx.age.item(&store, age42).unwrap().unwrap(); - assert_eq!(String::from_vec(k).unwrap(), pks[0]); - assert_eq!(v.name, datas[0].name); - assert_eq!(v.age, datas[0].age); - - // match on other age - let age23 = 23u32; - let (k, v) = map.idx.age.item(&store, age23).unwrap().unwrap(); - assert_eq!(String::from_vec(k).unwrap(), pks[1]); - assert_eq!(v.name, datas[1].name); - assert_eq!(v.age, datas[1].age); - - // if we delete the first one, we can add the blocked one - map.remove(&mut store, pks[0]).unwrap(); - map.save(&mut store, pk5, &data5).unwrap(); - // now 42 is the new owner - let (k, v) = map.idx.age.item(&store, age42).unwrap().unwrap(); - assert_eq!(String::from_vec(k).unwrap(), pk5); - assert_eq!(v.name, data5.name); - assert_eq!(v.age, data5.age); - } - - #[test] - fn unique_index_enforced_composite_key() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - save_data(&mut store, &map); - - // same name, same lastname => error - let data5 = Data { - name: "Maria".to_string(), - last_name: "Doe".to_string(), - age: 24, - }; - let pk5 = "5"; - // enforce this returns some error - map.save(&mut store, pk5, &data5).unwrap_err(); - } - - #[test] - fn remove_and_update_reflected_on_indexes() { - let mut store = MockStorage::new(); - let map = build_map(); - - let name_count = |map: &IndexedMap<&str, Data, DataIndexes>, - store: &MemoryStorage, - name: &str| - -> usize { - map.idx - .name - .prefix(name.to_string()) - .keys_raw(store, None, None, Order::Ascending) - .count() - }; - - // save data - let (pks, _) = save_data(&mut store, &map); - - // find 2 Marias, 1 John, and no Mary - assert_eq!(name_count(&map, &store, "Maria"), 2); - assert_eq!(name_count(&map, &store, "John"), 1); - assert_eq!(name_count(&map, &store, "Maria Luisa"), 1); - assert_eq!(name_count(&map, &store, "Mary"), 0); - - // remove maria 2 - map.remove(&mut store, pks[1]).unwrap(); - - // change john to mary - map.update(&mut store, pks[2], |d| -> StdResult<_> { - let mut x = d.unwrap(); - assert_eq!(&x.name, "John"); - x.name = "Mary".to_string(); - Ok(x) - }) - .unwrap(); - - // find 1 maria, 1 maria luisa, no john, and 1 mary - assert_eq!(name_count(&map, &store, "Maria"), 1); - assert_eq!(name_count(&map, &store, "Maria Luisa"), 1); - assert_eq!(name_count(&map, &store, "John"), 0); - assert_eq!(name_count(&map, &store, "Mary"), 1); - } - - #[test] - fn range_raw_simple_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .age - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let ages = res.unwrap(); - - let count = ages.len(); - assert_eq!(5, count); - - // The pks, sorted by age ascending - assert_eq!(pks[3], String::from_slice(&ages[0].0).unwrap()); // 12 - assert_eq!(pks[1], String::from_slice(&ages[1].0).unwrap()); // 23 - assert_eq!(pks[2], String::from_slice(&ages[2].0).unwrap()); // 32 - assert_eq!(pks[0], String::from_slice(&ages[3].0).unwrap()); // 42 - assert_eq!(pks[4], String::from_slice(&ages[4].0).unwrap()); // 90 - - // The associated data - assert_eq!(datas[3], ages[0].1); - assert_eq!(datas[1], ages[1].1); - assert_eq!(datas[2], ages[2].1); - assert_eq!(datas[0], ages[3].1); - assert_eq!(datas[4], ages[4].1); - } - - #[test] - fn range_simple_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .age - .range(&store, None, None, Order::Ascending) - .collect(); - let ages = res.unwrap(); - - let count = ages.len(); - assert_eq!(5, count); - - // The pks, sorted by age ascending - assert_eq!(pks[3], ages[0].0); - assert_eq!(pks[1], ages[1].0); - assert_eq!(pks[2], ages[2].0); - assert_eq!(pks[0], ages[3].0); - assert_eq!(pks[4], ages[4].0); - - // The associated data - assert_eq!(datas[3], ages[0].1); - assert_eq!(datas[1], ages[1].1); - assert_eq!(datas[2], ages[2].1); - assert_eq!(datas[0], ages[3].1); - assert_eq!(datas[4], ages[4].1); - } - - #[test] - fn range_raw_composite_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .name_lastname - .prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let marias = res.unwrap(); - - // Only two people are called "Maria" - let count = marias.len(); - assert_eq!(2, count); - - // The pks - assert_eq!(pks[0], String::from_slice(&marias[0].0).unwrap()); - assert_eq!(pks[1], String::from_slice(&marias[1].0).unwrap()); - - // The associated data - assert_eq!(datas[0], marias[0].1); - assert_eq!(datas[1], marias[1].1); - } - - #[test] - fn range_composite_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .name_lastname - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) - .collect(); - let marias = res.unwrap(); - - // Only two people are called "Maria" - let count = marias.len(); - assert_eq!(2, count); - - // The pks - assert_eq!(pks[0], marias[0].0); - assert_eq!(pks[1], marias[1].0); - - // The associated data - assert_eq!(datas[0], marias[0].1); - assert_eq!(datas[1], marias[1].1); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_simple_string_key() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // let's try to iterate! - let all: StdResult> = map.range(&store, None, None, Order::Ascending).collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.clone() - .into_iter() - .map(str::to_string) - .zip(datas.clone().into_iter()) - .collect::>() - ); - - // let's try to iterate over a range - let all: StdResult> = map - .range(&store, Some(Bound::inclusive("3")), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.into_iter() - .map(str::to_string) - .zip(datas.into_iter()) - .rev() - .take(3) - .rev() - .collect::>() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_simple_string_key() { - let mut store = MockStorage::new(); - let map = build_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // Let's prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / prefix - // type checks - let all: StdResult> = map - .prefix(()) - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.clone() - .into_iter() - .map(str::to_string) - .zip(datas.into_iter()) - .collect::>() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_composite_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = ("1", "5627"); - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = ("2", "5628"); - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = ("2", "5629"); - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = ("3", "5630"); - map.save(&mut store, pk4, &data4).unwrap(); - - // let's prefix and iterate - let result: StdResult> = map - .prefix("2") - .range(&store, None, None, Order::Ascending) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [("5628".to_string(), data2), ("5629".to_string(), data3),] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_triple_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = ("1", "1", "5627"); - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = ("1", "2", "5628"); - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = ("2", "1", "5629"); - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = ("2", "2", "5630"); - map.save(&mut store, pk4, &data4).unwrap(); - - // let's prefix and iterate - let result: StdResult> = map - .prefix(("1", "2")) - .range(&store, None, None, Order::Ascending) - .collect(); - let result = result.unwrap(); - assert_eq!(result, [("5628".to_string(), data2),]); - } - - #[test] - #[cfg(feature = "iterator")] - fn sub_prefix_triple_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = ("1", "1", "5627"); - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = ("1", "2", "5628"); - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = ("2", "1", "5629"); - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = ("2", "2", "5630"); - map.save(&mut store, pk4, &data4).unwrap(); - - // let's sub-prefix and iterate - let result: StdResult> = map - .sub_prefix("1") - .range(&store, None, None, Order::Ascending) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - (("1".to_string(), "5627".to_string()), data1), - (("2".to_string(), "5628".to_string()), data2), - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_range_simple_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = ("1", "5627"); - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = ("2", "5628"); - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = ("2", "5629"); - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = ("3", "5630"); - map.save(&mut store, pk4, &data4).unwrap(); - - // let's prefix-range and iterate - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive("2")), - None, - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - (("2".to_string(), "5628".to_string()), data2.clone()), - (("2".to_string(), "5629".to_string()), data3.clone()), - (("3".to_string(), "5630".to_string()), data4) - ] - ); - - // let's try to iterate over a more restrictive prefix-range! - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive("2")), - Some(PrefixBound::exclusive("3")), - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - (("2".to_string(), "5628".to_string()), data2), - (("2".to_string(), "5629".to_string()), data3), - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_range_triple_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = IndexedMap::new("data", indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = ("1", "1", "5627"); - map.save(&mut store, pk1, &data1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = ("1", "2", "5628"); - map.save(&mut store, pk2, &data2).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = ("2", "1", "5629"); - map.save(&mut store, pk3, &data3).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = ("2", "2", "5630"); - map.save(&mut store, pk4, &data4).unwrap(); - - // let's prefix-range and iterate - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive(("1", "2"))), - None, - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - ( - ("1".to_string(), "2".to_string(), "5628".to_string()), - data2.clone() - ), - ( - ("2".to_string(), "1".to_string(), "5629".to_string()), - data3.clone() - ), - ( - ("2".to_string(), "2".to_string(), "5630".to_string()), - data4 - ) - ] - ); - - // let's prefix-range over inclusive bounds on both sides - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive(("1", "2"))), - Some(PrefixBound::inclusive(("2", "1"))), - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - ( - ("1".to_string(), "2".to_string(), "5628".to_string()), - data2 - ), - ( - ("2".to_string(), "1".to_string(), "5629".to_string()), - data3 - ), - ] - ); - } - - mod bounds_unique_index { - use super::*; - - struct Indexes<'a> { - secondary: UniqueIndex<'a, u64, u64>, - } - - impl<'a> IndexList for Indexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.secondary]; - Box::new(v.into_iter()) - } - } - - #[test] - #[cfg(feature = "iterator")] - fn composite_key_query() { - let indexes = Indexes { - secondary: UniqueIndex::new(|secondary| *secondary, "test_map__secondary"), - }; - let map = IndexedMap::<&str, u64, Indexes>::new("test_map", indexes); - let mut store = MockStorage::new(); - - map.save(&mut store, "one", &1).unwrap(); - map.save(&mut store, "two", &2).unwrap(); - map.save(&mut store, "three", &3).unwrap(); - - // Inclusive bound - let items: Vec<_> = map - .idx - .secondary - .range_raw(&store, None, Some(Bound::inclusive(1u64)), Order::Ascending) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v).collect(); - - assert_eq!(items, vec![1]); - - // Exclusive bound - let items: Vec<_> = map - .idx - .secondary - .range(&store, Some(Bound::exclusive(2u64)), None, Order::Ascending) - .collect::>() - .unwrap(); - - assert_eq!(items, vec![((), 3)]); - } - } - - mod bounds_multi_index { - use super::*; - - struct Indexes<'a> { - // The last type param must match the `IndexedMap` primary key type, below - secondary: MultiIndex<'a, u64, u64, &'a str>, - } - - impl<'a> IndexList for Indexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.secondary]; - Box::new(v.into_iter()) - } - } - - #[test] - #[cfg(feature = "iterator")] - fn composite_key_query() { - let indexes = Indexes { - secondary: MultiIndex::new( - |_pk, secondary| *secondary, - "test_map", - "test_map__secondary", - ), - }; - let map = IndexedMap::<&str, u64, Indexes>::new("test_map", indexes); - let mut store = MockStorage::new(); - - map.save(&mut store, "one", &1).unwrap(); - map.save(&mut store, "two", &2).unwrap(); - map.save(&mut store, "two2", &2).unwrap(); - map.save(&mut store, "three", &3).unwrap(); - - // Inclusive prefix-bound - let items: Vec<_> = map - .idx - .secondary - .prefix_range_raw( - &store, - None, - Some(PrefixBound::inclusive(1u64)), - Order::Ascending, - ) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v).collect(); - - assert_eq!(items, vec![1]); - - // Exclusive bound (used for pagination) - // Range over the index specifying a primary key (multi-index key includes the pk) - let items: Vec<_> = map - .idx - .secondary - .range( - &store, - Some(Bound::exclusive((2u64, "two"))), - None, - Order::Ascending, - ) - .collect::>() - .unwrap(); - - assert_eq!( - items, - vec![("two2".to_string(), 2), ("three".to_string(), 3)] - ); - } - } - - mod pk_multi_index { - use super::*; - use cosmwasm_std::{Addr, Uint128}; - - struct Indexes<'a> { - // The last type param must match the `IndexedMap` primary key type below - spender: MultiIndex<'a, Addr, Uint128, (Addr, Addr)>, - } - - impl<'a> IndexList for Indexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.spender]; - Box::new(v.into_iter()) - } - } - - #[test] - #[cfg(feature = "iterator")] - fn pk_based_index() { - fn pk_index(pk: &[u8]) -> Addr { - let (_owner, spender) = <(Addr, Addr)>::from_slice(pk).unwrap(); // mustn't fail - spender - } - - let indexes = Indexes { - spender: MultiIndex::new( - |pk, _allow| pk_index(pk), - "allowances", - "allowances__spender", - ), - }; - let map = IndexedMap::<(&Addr, &Addr), Uint128, Indexes>::new("allowances", indexes); - let mut store = MockStorage::new(); - - map.save( - &mut store, - (&Addr::unchecked("owner1"), &Addr::unchecked("spender1")), - &Uint128::new(11), - ) - .unwrap(); - map.save( - &mut store, - (&Addr::unchecked("owner1"), &Addr::unchecked("spender2")), - &Uint128::new(12), - ) - .unwrap(); - map.save( - &mut store, - (&Addr::unchecked("owner2"), &Addr::unchecked("spender1")), - &Uint128::new(21), - ) - .unwrap(); - - // Iterate over the main values - let items: Vec<_> = map - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); - - assert_eq!(items, vec![11, 12, 21]); - - // Iterate over the indexed values - let items: Vec<_> = map - .idx - .spender - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); - - assert_eq!(items, vec![11, 21, 12]); - - // Prefix over the main values - let items: Vec<_> = map - .prefix(&Addr::unchecked("owner1")) - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); - - assert_eq!(items, vec![11, 12]); - - // Prefix over the indexed values - let items: Vec<_> = map - .idx - .spender - .prefix(Addr::unchecked("spender1")) - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - - // Strip the index from values (for simpler comparison) - let items: Vec<_> = items.into_iter().map(|(_, v)| v.u128()).collect(); - - assert_eq!(items, vec![11, 21]); - - // Prefix over the indexed values, and deserialize primary key as well - let items: Vec<_> = map - .idx - .spender - .prefix(Addr::unchecked("spender2")) - .range(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - - assert_eq!( - items, - vec![( - (Addr::unchecked("owner1"), Addr::unchecked("spender2")), - Uint128::new(12) - )] - ); - } - } - - #[test] - fn clear_works() { - let mut storage = MockStorage::new(); - let map = build_map(); - let (pks, _) = save_data(&mut storage, &map); - - map.clear(&mut storage); - - for key in pks { - assert!(!map.has(&storage, key)); - } - } - - #[test] - fn is_empty_works() { - let mut storage = MockStorage::new(); - let map = build_map(); - - assert!(map.is_empty(&storage)); - - save_data(&mut storage, &map); - - assert!(!map.is_empty(&storage)); - } -} diff --git a/packages/storage-plus/src/indexed_snapshot.rs b/packages/storage-plus/src/indexed_snapshot.rs deleted file mode 100644 index 146fc0d0f..000000000 --- a/packages/storage-plus/src/indexed_snapshot.rs +++ /dev/null @@ -1,1224 +0,0 @@ -// this module requires iterator to be useful at all -#![cfg(feature = "iterator")] - -use cosmwasm_std::{StdError, StdResult, Storage}; -use serde::de::DeserializeOwned; -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}; -use crate::snapshot::{ChangeSet, SnapshotMap}; -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> { - pk_namespace: &'a [u8], - primary: SnapshotMap<'a, K, T>, - /// This is meant to be read directly to get the proper types, like: - /// map.idx.owner.items(...) - pub idx: I, -} - -impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> { - /// Examples: - /// - /// ```rust - /// use cw_storage_plus::{IndexedSnapshotMap, Strategy, UniqueIndex}; - /// - /// #[derive(PartialEq, Debug, Clone)] - /// struct Data { - /// pub name: String, - /// pub age: u32, - /// } - /// - /// let indexes = UniqueIndex::new(|d: &Data| d.age, "data__age"); - /// - /// IndexedSnapshotMap::<&[u8], Data, UniqueIndex>::new( - /// "data", - /// "checkpoints", - /// "changelog", - /// Strategy::EveryBlock, - /// indexes, - /// ); - /// ``` - pub fn new( - pk_namespace: &'a str, - checkpoints: &'a str, - changelog: &'a str, - strategy: Strategy, - indexes: I, - ) -> Self { - IndexedSnapshotMap { - pk_namespace: pk_namespace.as_bytes(), - primary: SnapshotMap::new(pk_namespace, checkpoints, changelog, strategy), - idx: indexes, - } - } - - pub fn changelog(&self) -> &Map<'a, (K, u64), ChangeSet> { - self.primary.changelog() - } -} - -impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, - I: IndexList, -{ - pub fn add_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.primary.add_checkpoint(store, height) - } - - pub fn remove_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.primary.remove_checkpoint(store, height) - } - - pub fn may_load_at_height( - &self, - store: &dyn Storage, - k: K, - height: u64, - ) -> StdResult> { - self.primary.may_load_at_height(store, k, height) - } - - pub fn assert_checkpointed(&self, store: &dyn Storage, height: u64) -> StdResult<()> { - self.primary.assert_checkpointed(store, height) - } - - pub fn key(&self, k: K) -> Path { - self.primary.key(k) - } -} - -impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> -where - K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, - T: Serialize + DeserializeOwned + Clone, - I: IndexList, -{ - /// save will serialize the model and store, returns an error on serialization issues. - /// this must load the old value to update the indexes properly - /// if you loaded the old value earlier in the same function, use replace to avoid needless db reads - pub fn save(&self, store: &mut dyn Storage, key: K, data: &T, height: u64) -> StdResult<()> { - let old_data = self.may_load(store, key.clone())?; - self.replace(store, key, Some(data), old_data.as_ref(), height) - } - - pub fn remove(&self, store: &mut dyn Storage, key: K, height: u64) -> StdResult<()> { - let old_data = self.may_load(store, key.clone())?; - self.replace(store, key, None, old_data.as_ref(), height) - } - - /// replace writes data to key. old_data must be the current stored value (from a previous load) - /// and is used to properly update the index. This is used by save, replace, and update - /// and can be called directly if you want to optimize - pub fn replace( - &self, - store: &mut dyn Storage, - key: K, - data: Option<&T>, - old_data: Option<&T>, - height: u64, - ) -> StdResult<()> { - // this is the key *relative* to the primary map namespace - let pk = key.joined_key(); - if let Some(old) = old_data { - for index in self.idx.get_indexes() { - index.remove(store, &pk, old)?; - } - } - if let Some(updated) = data { - for index in self.idx.get_indexes() { - index.save(store, &pk, updated)?; - } - self.primary.save(store, key, updated, height)?; - } else { - self.primary.remove(store, key, height)?; - } - Ok(()) - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - pub fn update( - &self, - store: &mut dyn Storage, - key: K, - height: u64, - action: A, - ) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - let input = self.may_load(store, key.clone())?; - let old_val = input.clone(); - let output = action(input)?; - self.replace(store, key, Some(&output), old_val.as_ref(), height)?; - Ok(output) - } - - // Everything else, that doesn't touch indexers, is just pass-through from self.core, - // thus can be used from while iterating over indexes - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage, key: K) -> StdResult { - self.primary.load(store, key) - } - - /// may_load will parse the data stored at the key if present, returns Ok(None) if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage, key: K) -> StdResult> { - self.primary.may_load(store, key) - } - - // use no_prefix to scan -> range - pub 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> IndexedSnapshotMap<'a, K, T, I> -where - K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, - 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> IndexedSnapshotMap<'a, K, T, I> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a>, - I: IndexList, -{ - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { - Prefix::new(self.pk_namespace, &p.prefix()) - } - - pub fn prefix(&self, p: K::Prefix) -> Prefix { - Prefix::new(self.pk_namespace, &p.prefix()) - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T, I> IndexedSnapshotMap<'a, K, T, I> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + KeyDeserialize, - I: IndexList, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - K: 'c, - K::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.pk_namespace, min, max, order) - .map(deserialize_kv::); - Box::new(mapped) - } - - pub fn range<'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().range(store, min, max, order) - } - - pub fn keys<'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().keys(store, min, max, order) - } - - fn no_prefix(&self) -> Prefix { - Prefix::new(self.pk_namespace, &[]) - } -} - -#[cfg(test)] -mod test { - use super::*; - - use crate::indexes::test::{index_string_tuple, index_tuple}; - use crate::{Index, MultiIndex, UniqueIndex}; - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::{MemoryStorage, Order}; - use serde::{Deserialize, Serialize}; - - #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] - struct Data { - pub name: String, - pub last_name: String, - pub age: u32, - } - - struct DataIndexes<'a> { - // Last type parameters are for signaling pk deserialization - pub name: MultiIndex<'a, Vec, Data, String>, - pub age: UniqueIndex<'a, u32, Data, String>, - pub name_lastname: UniqueIndex<'a, (Vec, Vec), Data, String>, - } - - // Future Note: this can likely be macro-derived - impl<'a> IndexList for DataIndexes<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.name, &self.age, &self.name_lastname]; - Box::new(v.into_iter()) - } - } - - // For composite multi index tests - struct DataCompositeMultiIndex<'a> { - // Last type parameter is for signaling pk deserialization - pub name_age: MultiIndex<'a, (Vec, u32), Data, String>, - } - - // Future Note: this can likely be macro-derived - impl<'a> IndexList for DataCompositeMultiIndex<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.name_age]; - Box::new(v.into_iter()) - } - } - - // Can we make it easier to define this? (less wordy generic) - fn build_snapshot_map<'a>() -> IndexedSnapshotMap<'a, &'a str, Data, DataIndexes<'a>> { - let indexes = DataIndexes { - name: MultiIndex::new(|_pk, d| d.name.as_bytes().to_vec(), "data", "data__name"), - age: UniqueIndex::new(|d| d.age, "data__age"), - name_lastname: UniqueIndex::new( - |d| index_string_tuple(&d.name, &d.last_name), - "data__name_lastname", - ), - }; - IndexedSnapshotMap::new( - "data", - "checkpoints", - "changelog", - Strategy::EveryBlock, - indexes, - ) - } - - fn save_data<'a>( - store: &mut MockStorage, - map: &IndexedSnapshotMap<'a, &'a str, Data, DataIndexes<'a>>, - ) -> (Vec<&'a str>, Vec) { - let mut pks = vec![]; - let mut datas = vec![]; - let mut height = 0; - let data = Data { - name: "Maria".to_string(), - last_name: "Doe".to_string(), - age: 42, - }; - let pk = "1"; - map.save(store, pk, &data, height).unwrap(); - height += 1; - pks.push(pk); - datas.push(data); - - // same name (multi-index), different last name, different age => ok - let data = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 23, - }; - let pk = "2"; - map.save(store, pk, &data, height).unwrap(); - height += 1; - pks.push(pk); - datas.push(data); - - // different name, different last name, different age => ok - let data = Data { - name: "John".to_string(), - last_name: "Wayne".to_string(), - age: 32, - }; - let pk = "3"; - map.save(store, pk, &data, height).unwrap(); - height += 1; - pks.push(pk); - datas.push(data); - - let data = Data { - name: "Maria Luisa".to_string(), - last_name: "Rodriguez".to_string(), - age: 12, - }; - let pk = "4"; - map.save(store, pk, &data, height).unwrap(); - pks.push(pk); - datas.push(data); - - (pks, datas) - } - - #[test] - fn store_and_load_by_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - let pk = pks[0]; - let data = &datas[0]; - - // load it properly - let loaded = map.load(&store, pk).unwrap(); - assert_eq!(*data, loaded); - - let count = map - .idx - .name - .prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(2, count); - - // load it by secondary index - let marias: Vec<_> = map - .idx - .name - .prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - assert_eq!(2, marias.len()); - let (k, v) = &marias[0]; - assert_eq!(pk.as_bytes(), k); - assert_eq!(data, v); - - // other index doesn't match (1 byte after) - let count = map - .idx - .name - .prefix(b"Marib".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // other index doesn't match (1 byte before) - let count = map - .idx - .name - .prefix(b"Mari`".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // other index doesn't match (longer) - let count = map - .idx - .name - .prefix(b"Maria5".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .count(); - assert_eq!(0, count); - - // match on proper age - let proper = 42u32; - let aged = map.idx.age.item(&store, proper).unwrap().unwrap(); - assert_eq!(pk.as_bytes(), aged.0); - assert_eq!(*data, aged.1); - - // no match on wrong age - let too_old = 43u32; - let aged = map.idx.age.item(&store, too_old).unwrap(); - assert_eq!(None, aged); - } - - #[test] - fn range_raw_simple_key_by_multi_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let mut height = 1; - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk = "5627"; - map.save(&mut store, pk, &data1, height).unwrap(); - height += 1; - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk = "5628"; - map.save(&mut store, pk, &data2, height).unwrap(); - height += 1; - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 24, - }; - let pk = "5629"; - map.save(&mut store, pk, &data3, height).unwrap(); - height += 1; - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 12, - }; - let pk = "5630"; - map.save(&mut store, pk, &data4, height).unwrap(); - - let marias: Vec<_> = map - .idx - .name - .prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Sorted by (descending) pk - assert_eq!(marias[0].0, b"5629"); - assert_eq!(marias[1].0, b"5627"); - // Data is correct - assert_eq!(marias[0].1, data3); - assert_eq!(marias[1].1, data1); - } - - #[test] - fn range_simple_key_by_multi_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let mut height = 1; - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk = "5627"; - map.save(&mut store, pk, &data1, height).unwrap(); - height += 1; - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk = "5628"; - map.save(&mut store, pk, &data2, height).unwrap(); - height += 1; - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 24, - }; - let pk = "5629"; - map.save(&mut store, pk, &data3, height).unwrap(); - height += 1; - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 12, - }; - let pk = "5630"; - map.save(&mut store, pk, &data4, height).unwrap(); - - let marias: Vec<_> = map - .idx - .name - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Sorted by (descending) pk - assert_eq!(marias[0].0, "5629"); - assert_eq!(marias[1].0, "5627"); - // Data is correct - assert_eq!(marias[0].1, data3); - assert_eq!(marias[1].1, data1); - } - - #[test] - fn changelog_range_works() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let mut height = 1; - - // simple data for testing - // EVERY.remove(&mut store, "B", 4).unwrap(); - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk_a = "A"; - map.save(&mut store, pk_a, &data1, height).unwrap(); - height += 1; - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk_b = "B"; - map.save(&mut store, pk_b, &data2, height).unwrap(); - height += 1; - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Williams".to_string(), - age: 24, - }; - map.update(&mut store, pk_a, height, |_| -> StdResult { - Ok(data3) - }) - .unwrap(); - - height += 1; - map.remove(&mut store, pk_b, height).unwrap(); - - let changes: Vec<_> = map - .changelog() - .range(&store, None, None, Order::Ascending) - .collect::>() - .unwrap(); - let count = changes.len(); - assert_eq!(4, count); - - // sorted by ascending key, height - assert_eq!( - changes, - vec![ - (("A".into(), 1), ChangeSet { old: None }), - (("A".into(), 3), ChangeSet { old: Some(data1) }), - (("B".into(), 2), ChangeSet { old: None }), - (("B".into(), 4), ChangeSet { old: Some(data2) }) - ] - ); - } - - #[test] - fn range_raw_composite_key_by_multi_index() { - let mut store = MockStorage::new(); - let mut height = 2; - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = - IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = "5627"; - map.save(&mut store, pk1, &data1, height).unwrap(); - height += 1; - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = "5628"; - map.save(&mut store, pk2, &data2, height).unwrap(); - height += 1; - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = "5629"; - map.save(&mut store, pk3, &data3, height).unwrap(); - height += 1; - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = "5630"; - map.save(&mut store, pk4, &data4, height).unwrap(); - - let marias: Vec<_> = map - .idx - .name_age - .sub_prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks (sorted by age descending) - assert_eq!(pk1.as_bytes(), marias[0].0); - assert_eq!(pk3.as_bytes(), marias[1].0); - - // Data - assert_eq!(data1, marias[0].1); - assert_eq!(data3, marias[1].1); - } - - #[test] - fn range_composite_key_by_multi_index() { - let mut store = MockStorage::new(); - let mut height = 2; - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = - IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1 = "5627"; - map.save(&mut store, pk1, &data1, height).unwrap(); - height += 1; - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2 = "5628"; - map.save(&mut store, pk2, &data2, height).unwrap(); - height += 1; - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3 = "5629"; - map.save(&mut store, pk3, &data3, height).unwrap(); - height += 1; - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4 = "5630"; - map.save(&mut store, pk4, &data4, height).unwrap(); - - let marias: Vec<_> = map - .idx - .name_age - .sub_prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Descending) - .collect::>() - .unwrap(); - let count = marias.len(); - assert_eq!(2, count); - - // Pks (sorted by age descending) - assert_eq!(pk1.to_string(), marias[0].0); - assert_eq!(pk3.to_string(), marias[1].0); - - // Data - assert_eq!(data1, marias[0].1); - assert_eq!(data3, marias[1].1); - } - - #[test] - fn unique_index_enforced() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let mut height = 3; - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // different name, different last name, same age => error - let data5 = Data { - name: "Marta".to_string(), - last_name: "Laurens".to_string(), - age: 42, - }; - let pk5 = "4"; - - // enforce this returns some error - map.save(&mut store, pk5, &data5, height).unwrap_err(); - height += 1; - - // query by unique key - // match on proper age - let age42 = 42u32; - let (k, v) = map.idx.age.item(&store, age42).unwrap().unwrap(); - assert_eq!(k, pks[0].as_bytes()); - assert_eq!(v.name, datas[0].name); - assert_eq!(v.age, datas[0].age); - - // match on other age - let age23 = 23u32; - let (k, v) = map.idx.age.item(&store, age23).unwrap().unwrap(); - assert_eq!(k, pks[1].as_bytes()); - assert_eq!(v.name, datas[1].name); - assert_eq!(v.age, datas[1].age); - - // if we delete the first one, we can add the blocked one - map.remove(&mut store, pks[0], height).unwrap(); - height += 1; - map.save(&mut store, pk5, &data5, height).unwrap(); - // now 42 is the new owner - let (k, v) = map.idx.age.item(&store, age42).unwrap().unwrap(); - assert_eq!(k, pk5.as_bytes()); - assert_eq!(v.name, data5.name); - assert_eq!(v.age, data5.age); - } - - #[test] - fn unique_index_enforced_composite_key() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let height = 4; - - // save data - save_data(&mut store, &map); - - // same name, same lastname => error - let data5 = Data { - name: "Maria".to_string(), - last_name: "Doe".to_string(), - age: 24, - }; - let pk5 = "5"; - // enforce this returns some error - map.save(&mut store, pk5, &data5, height).unwrap_err(); - } - - #[test] - fn remove_and_update_reflected_on_indexes() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - let mut height = 5; - - let name_count = |map: &IndexedSnapshotMap<&str, Data, DataIndexes>, - store: &MemoryStorage, - name: &str| - -> usize { - map.idx - .name - .prefix(name.as_bytes().to_vec()) - .keys_raw(store, None, None, Order::Ascending) - .count() - }; - - // save data - let (pks, _) = save_data(&mut store, &map); - - // find 2 Marias, 1 John, and no Mary - assert_eq!(name_count(&map, &store, "Maria"), 2); - assert_eq!(name_count(&map, &store, "John"), 1); - assert_eq!(name_count(&map, &store, "Maria Luisa"), 1); - assert_eq!(name_count(&map, &store, "Mary"), 0); - - // remove maria 2 - map.remove(&mut store, pks[1], height).unwrap(); - height += 1; - - // change john to mary - map.update(&mut store, pks[2], height, |d| -> StdResult<_> { - let mut x = d.unwrap(); - assert_eq!(&x.name, "John"); - x.name = "Mary".to_string(); - Ok(x) - }) - .unwrap(); - - // find 1 maria, 1 maria luisa, no john, and 1 mary - assert_eq!(name_count(&map, &store, "Maria"), 1); - assert_eq!(name_count(&map, &store, "Maria Luisa"), 1); - assert_eq!(name_count(&map, &store, "John"), 0); - assert_eq!(name_count(&map, &store, "Mary"), 1); - } - - #[test] - fn range_raw_simple_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .age - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let ages = res.unwrap(); - - let count = ages.len(); - assert_eq!(4, count); - - // The pks, sorted by age ascending - assert_eq!(pks[3].as_bytes(), ages[0].0); - assert_eq!(pks[1].as_bytes(), ages[1].0); - assert_eq!(pks[2].as_bytes(), ages[2].0); - assert_eq!(pks[0].as_bytes(), ages[3].0); - - // The associated data - assert_eq!(datas[3], ages[0].1); - assert_eq!(datas[1], ages[1].1); - assert_eq!(datas[2], ages[2].1); - assert_eq!(datas[0], ages[3].1); - } - - #[test] - fn range_simple_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .age - .range(&store, None, None, Order::Ascending) - .collect(); - let ages = res.unwrap(); - - let count = ages.len(); - assert_eq!(4, count); - - // The pks, sorted by age ascending - assert_eq!(pks[3], ages[0].0); - assert_eq!(pks[1], ages[1].0); - assert_eq!(pks[2], ages[2].0); - assert_eq!(pks[0], ages[3].0); - - // The associated data - assert_eq!(datas[3], ages[0].1); - assert_eq!(datas[1], ages[1].1); - assert_eq!(datas[2], ages[2].1); - assert_eq!(datas[0], ages[3].1); - } - - #[test] - fn range_raw_composite_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .name_lastname - .prefix(b"Maria".to_vec()) - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let marias = res.unwrap(); - - // Only two people are called "Maria" - let count = marias.len(); - assert_eq!(2, count); - - // The pks - assert_eq!(pks[0].as_bytes(), marias[0].0); - assert_eq!(pks[1].as_bytes(), marias[1].0); - - // The associated data - assert_eq!(datas[0], marias[0].1); - assert_eq!(datas[1], marias[1].1); - } - - #[test] - fn range_composite_key_by_unique_index() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - let res: StdResult> = map - .idx - .name_lastname - .prefix(b"Maria".to_vec()) - .range(&store, None, None, Order::Ascending) - .collect(); - let marias = res.unwrap(); - - // Only two people are called "Maria" - let count = marias.len(); - assert_eq!(2, count); - - // The pks - assert_eq!(pks[0], marias[0].0); - assert_eq!(pks[1], marias[1].0); - - // The associated data - assert_eq!(datas[0], marias[0].1); - assert_eq!(datas[1], marias[1].1); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_simple_string_key() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // let's try to iterate! - let all: StdResult> = map.range(&store, None, None, Order::Ascending).collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.clone() - .into_iter() - .map(str::to_string) - .zip(datas.clone().into_iter()) - .collect::>() - ); - - // let's try to iterate over a range - let all: StdResult> = map - .range(&store, Some(Bound::inclusive("3")), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.into_iter() - .map(str::to_string) - .zip(datas.into_iter()) - .rev() - .take(2) - .rev() - .collect::>() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_simple_string_key() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // Let's prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / prefix - // type checks - let all: StdResult> = map - .prefix(()) - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.clone() - .into_iter() - .map(str::to_string) - .zip(datas.into_iter()) - .collect::>() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn sub_prefix_simple_string_key() { - let mut store = MockStorage::new(); - let map = build_snapshot_map(); - - // save data - let (pks, datas) = save_data(&mut store, &map); - - // Let's sub-prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / sub_prefix - // type checks - let all: StdResult> = map - .sub_prefix(()) - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!( - all, - pks.clone() - .into_iter() - .map(str::to_string) - .zip(datas.into_iter()) - .collect::>() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_range_simple_key() { - let mut store = MockStorage::new(); - - let indexes = DataCompositeMultiIndex { - name_age: MultiIndex::new( - |_pk, d| index_tuple(&d.name, d.age), - "data", - "data__name_age", - ), - }; - let map = - IndexedSnapshotMap::new("data", "checks", "changes", Strategy::EveryBlock, indexes); - - // save data - let data1 = Data { - name: "Maria".to_string(), - last_name: "".to_string(), - age: 42, - }; - let pk1: (&str, &str) = ("1", "5627"); - map.save(&mut store, pk1, &data1, 1).unwrap(); - - let data2 = Data { - name: "Juan".to_string(), - last_name: "Perez".to_string(), - age: 13, - }; - let pk2: (&str, &str) = ("2", "5628"); - map.save(&mut store, pk2, &data2, 1).unwrap(); - - let data3 = Data { - name: "Maria".to_string(), - last_name: "Young".to_string(), - age: 24, - }; - let pk3: (&str, &str) = ("2", "5629"); - map.save(&mut store, pk3, &data3, 1).unwrap(); - - let data4 = Data { - name: "Maria Luisa".to_string(), - last_name: "Bemberg".to_string(), - age: 43, - }; - let pk4: (&str, &str) = ("3", "5630"); - map.save(&mut store, pk4, &data4, 1).unwrap(); - - // let's prefix-range and iterate - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive("2")), - None, - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - (("2".to_string(), "5628".to_string()), data2.clone()), - (("2".to_string(), "5629".to_string()), data3.clone()), - (("3".to_string(), "5630".to_string()), data4) - ] - ); - - // let's try to iterate over a more restrictive prefix-range! - let result: StdResult> = map - .prefix_range( - &store, - Some(PrefixBound::inclusive("2")), - Some(PrefixBound::exclusive("3")), - Order::Ascending, - ) - .collect(); - let result = result.unwrap(); - assert_eq!( - result, - [ - (("2".to_string(), "5628".to_string()), data2), - (("2".to_string(), "5629".to_string()), data3), - ] - ); - } -} diff --git a/packages/storage-plus/src/indexes/mod.rs b/packages/storage-plus/src/indexes/mod.rs deleted file mode 100644 index e2639ac83..000000000 --- a/packages/storage-plus/src/indexes/mod.rs +++ /dev/null @@ -1,38 +0,0 @@ -// this module requires iterator to be useful at all -#![cfg(feature = "iterator")] -mod multi; -mod unique; - -pub use multi::MultiIndex; -pub use unique::UniqueIndex; - -use serde::de::DeserializeOwned; -use serde::Serialize; - -use cosmwasm_std::{StdResult, Storage}; - -// Note: we cannot store traits with generic functions inside `Box`, -// so I pull S: Storage to a top-level -pub trait Index -where - T: Serialize + DeserializeOwned + Clone, -{ - fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()>; - fn remove(&self, store: &mut dyn Storage, pk: &[u8], old_data: &T) -> StdResult<()>; -} - -#[cfg(test)] -pub mod test { - - pub fn index_string(data: &str) -> Vec { - data.as_bytes().to_vec() - } - - pub fn index_tuple(name: &str, age: u32) -> (Vec, u32) { - (index_string(name), age) - } - - pub fn index_string_tuple(data1: &str, data2: &str) -> (Vec, Vec) { - (index_string(data1), index_string(data2)) - } -} diff --git a/packages/storage-plus/src/indexes/multi.rs b/packages/storage-plus/src/indexes/multi.rs deleted file mode 100644 index b40ee202e..000000000 --- a/packages/storage-plus/src/indexes/multi.rs +++ /dev/null @@ -1,346 +0,0 @@ -// this module requires iterator to be useful at all -#![cfg(feature = "iterator")] - -use serde::de::DeserializeOwned; -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; -use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; -use std::marker::PhantomData; - -/// MultiIndex stores (namespace, index_name, idx_value, pk) -> b"pk_len". -/// Allows many values per index, and references pk. -/// The associated primary key value is stored in the main (pk_namespace) map, -/// which stores (namespace, pk_namespace, pk) -> value. -/// -/// The stored pk_len is used to recover the pk from the index namespace, and perform -/// the secondary load of the associated value from the main map. -/// -/// The PK type defines the type of Primary Key, both for deserialization, and -/// more important, as the type-safe bound key type. -/// This type must match the encompassing `IndexedMap` primary key type, -/// or its owned variant. -pub struct MultiIndex<'a, IK, T, PK> { - index: fn(&[u8], &T) -> IK, - idx_namespace: &'a [u8], - // note, we collapse the ik - combining everything under the namespace - and concatenating the pk - idx_map: Map<'a, Vec, u32>, - pk_namespace: &'a [u8], - phantom: PhantomData, -} - -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, -{ - // TODO: make this a const fn - /// Create a new MultiIndex - /// - /// idx_fn - lambda creating index key from value - /// pk_namespace - prefix for the primary key - /// idx_namespace - prefix for the index value - /// - /// ## Example: - /// - /// ```rust - /// use cw_storage_plus::MultiIndex; - /// use serde::{Deserialize, Serialize}; - /// - /// #[derive(Deserialize, Serialize, Clone)] - /// struct Data { - /// pub name: String, - /// pub age: u32, - /// } - /// - /// let index: MultiIndex<_, _, String> = MultiIndex::new( - /// |_pk: &[u8], d: &Data| d.age, - /// "age", - /// "age__owner", - /// ); - /// ``` - pub fn new(idx_fn: fn(&[u8], &T) -> IK, pk_namespace: &'a str, idx_namespace: &'a str) -> Self { - MultiIndex { - index: idx_fn, - idx_namespace: idx_namespace.as_bytes(), - idx_map: Map::new(idx_namespace), - pk_namespace: pk_namespace.as_bytes(), - phantom: PhantomData, - } - } -} - -fn deserialize_multi_v( - store: &dyn Storage, - pk_namespace: &[u8], - kv: Record, -) -> StdResult> { - let (key, pk_len) = kv; - - // Deserialize pk_len - let pk_len = from_slice::(pk_len.as_slice())?; - - // Recover pk from last part of k - let offset = key.len() - pk_len as usize; - let pk = &key[offset..]; - - let full_key = namespaces_with_key(&[pk_namespace], pk); - - let v = store - .get(&full_key) - .ok_or_else(|| StdError::generic_err("pk not found"))?; - let v = from_slice::(&v)?; - - Ok((pk.to_vec(), v)) -} - -fn deserialize_multi_kv( - store: &dyn Storage, - pk_namespace: &[u8], - kv: Record, -) -> StdResult<(K::Output, T)> { - let (key, pk_len) = kv; - - // Deserialize pk_len - let pk_len = from_slice::(pk_len.as_slice())?; - - // Recover pk from last part of k - let offset = key.len() - pk_len as usize; - let pk = &key[offset..]; - - let full_key = namespaces_with_key(&[pk_namespace], pk); - - let v = store - .get(&full_key) - .ok_or_else(|| StdError::generic_err("pk not found"))?; - let v = from_slice::(&v)?; - - // We return deserialized `pk` here for consistency - Ok((K::from_slice(pk)?, v)) -} - -impl<'a, IK, T, PK> Index for MultiIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a>, -{ - fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()> { - let idx = (self.index)(pk, data).joined_extra_key(pk); - self.idx_map.save(store, idx, &(pk.len() as u32)) - } - - fn remove(&self, store: &mut dyn Storage, pk: &[u8], old_data: &T) -> StdResult<()> { - let idx = (self.index)(pk, old_data).joined_extra_key(pk); - self.idx_map.remove(store, idx); - Ok(()) - } -} - -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a> + Prefixer<'a>, -{ - fn no_prefix_raw(&self) -> Prefix, T, (IK, PK)> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &[], - self.pk_namespace, - deserialize_multi_v, - deserialize_multi_v, - ) - } -} - -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - PK: PrimaryKey<'a> + KeyDeserialize, - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a> + Prefixer<'a>, -{ - pub fn index_key(&self, k: IK) -> Vec { - k.joined_extra_key(b"") - } - - #[cfg(test)] - pub fn count(&self, store: &dyn Storage, p: IK) -> usize { - let prefix = self.prefix(p); - prefix.keys_raw(store, None, None, Order::Ascending).count() - } - - #[cfg(test)] - pub fn all_pks(&self, store: &dyn Storage, p: IK) -> Vec> { - let prefix = self.prefix(p); - prefix - .keys_raw(store, None, None, Order::Ascending) - .collect::>>() - } - - #[cfg(test)] - pub fn all_items(&self, store: &dyn Storage, p: IK) -> StdResult>> { - let prefix = self.prefix(p); - prefix - .range_raw(store, None, None, Order::Ascending) - .collect() - } -} - -// short-cut for simple keys, rather than .prefix(()).range_raw(...) -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - 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>, - order: Order, - ) -> Box>> + 'c> - where - T: 'c, - { - self.no_prefix_raw().range_raw(store, min, max, order) - } - - pub fn keys_raw<'c>( - &'c self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: Order, - ) -> Box> + 'c> { - self.no_prefix_raw().keys_raw(store, min, max, order) - } - - /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range_raw<'c>( - &'c self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box>> + 'c> - where - T: 'c, - 'a: 'c, - { - let mapped = namespaced_prefix_range(store, self.idx_namespace, min, max, order) - .map(move |kv| (deserialize_multi_v)(store, self.pk_namespace, kv)); - Box::new(mapped) - } -} - -#[cfg(feature = "iterator")] -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - PK: PrimaryKey<'a> + KeyDeserialize, - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a> + Prefixer<'a>, -{ - pub fn prefix(&self, p: IK) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - self.pk_namespace, - deserialize_multi_kv::, - deserialize_multi_v, - ) - } - - pub fn sub_prefix(&self, p: IK::Prefix) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - self.pk_namespace, - deserialize_multi_kv::, - deserialize_multi_v, - ) - } -} - -#[cfg(feature = "iterator")] -impl<'a, IK, T, PK> MultiIndex<'a, IK, T, PK> -where - PK: PrimaryKey<'a> + KeyDeserialize, - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a> + KeyDeserialize + Prefixer<'a>, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - IK: 'c, - PK: 'c, - PK::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.idx_namespace, min, max, order) - .map(deserialize_kv::); - Box::new(mapped) - } - - pub fn range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - PK::Output: 'static, - { - self.no_prefix().range(store, min, max, order) - } - - pub fn keys<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - PK::Output: 'static, - { - self.no_prefix().keys(store, min, max, order) - } - - fn no_prefix(&self) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &[], - self.pk_namespace, - deserialize_multi_kv::, - deserialize_multi_v, - ) - } -} diff --git a/packages/storage-plus/src/indexes/unique.rs b/packages/storage-plus/src/indexes/unique.rs deleted file mode 100644 index 3143e5cff..000000000 --- a/packages/storage-plus/src/indexes/unique.rs +++ /dev/null @@ -1,257 +0,0 @@ -// this module requires iterator to be useful at all -#![cfg(feature = "iterator")] - -use std::marker::PhantomData; - -use serde::de::DeserializeOwned; -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; -use crate::{Bound, Index, Prefix, Prefixer, PrimaryKey}; - -/// UniqueRef stores Binary(Vec[u8]) representation of private key and index value -#[derive(Deserialize, Serialize)] -pub(crate) struct UniqueRef { - // note, we collapse the pk - combining everything under the namespace - even if it is composite - pk: Binary, - value: T, -} - -/// UniqueIndex stores (namespace, index_name, idx_value) -> {key, value} -/// Allows one value per index (i.e. unique) and copies pk and data -/// The optional PK type defines the type of Primary Key deserialization. -pub struct UniqueIndex<'a, IK, T, PK = ()> { - index: fn(&T) -> IK, - idx_map: Map<'a, IK, UniqueRef>, - idx_namespace: &'a [u8], - phantom: PhantomData, -} - -impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK> { - // TODO: make this a const fn - /// Create a new UniqueIndex - /// - /// idx_fn - lambda creating index key from index value - /// idx_namespace - prefix for the index value - /// - /// ## Example: - /// - /// ```rust - /// use cw_storage_plus::UniqueIndex; - /// - /// struct Data { - /// pub name: String, - /// pub age: u32, - /// } - /// - /// UniqueIndex::<_, _, ()>::new(|d: &Data| d.age, "data__age"); - /// ``` - pub fn new(idx_fn: fn(&T) -> IK, idx_namespace: &'a str) -> Self { - UniqueIndex { - index: idx_fn, - idx_map: Map::new(idx_namespace), - idx_namespace: idx_namespace.as_bytes(), - phantom: PhantomData, - } - } -} - -impl<'a, IK, T, PK> Index for UniqueIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a>, -{ - fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()> { - let idx = (self.index)(data); - // error if this is already set - self.idx_map - .update(store, idx, |existing| -> StdResult<_> { - match existing { - Some(_) => Err(StdError::generic_err("Violates unique constraint on index")), - None => Ok(UniqueRef:: { - pk: pk.into(), - value: data.clone(), - }), - } - })?; - Ok(()) - } - - fn remove(&self, store: &mut dyn Storage, _pk: &[u8], old_data: &T) -> StdResult<()> { - let idx = (self.index)(old_data); - self.idx_map.remove(store, idx); - Ok(()) - } -} - -fn deserialize_unique_v(kv: Record) -> StdResult> { - let (_, v) = kv; - let t = from_slice::>(&v)?; - Ok((t.pk.0, t.value)) -} - -fn deserialize_unique_kv( - kv: Record, -) -> StdResult<(K::Output, T)> { - let (_, v) = kv; - let t = from_slice::>(&v)?; - Ok((K::from_vec(t.pk.0)?, t.value)) -} - -impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a>, -{ - pub fn index_key(&self, k: IK) -> Vec { - k.joined_key() - } - - fn no_prefix_raw(&self) -> Prefix, T, IK> { - Prefix::with_deserialization_functions( - self.idx_namespace, - &[], - &[], - |_, _, kv| deserialize_unique_v(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } - - /// returns all items that match this secondary index, always by pk Ascending - pub fn item(&self, store: &dyn Storage, idx: IK) -> StdResult>> { - let data = self - .idx_map - .may_load(store, idx)? - .map(|i| (i.pk.into(), i.value)); - Ok(data) - } -} - -// short-cut for simple keys, rather than .prefix(()).range_raw(...) -impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK> -where - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a>, -{ - // 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: 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: Order, - ) -> Box> + 'c> { - self.no_prefix_raw().keys_raw(store, min, max, order) - } -} - -#[cfg(feature = "iterator")] -impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK> -where - PK: PrimaryKey<'a> + KeyDeserialize, - T: Serialize + DeserializeOwned + Clone, - IK: PrimaryKey<'a>, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - IK: 'c, - PK: 'c, - PK::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.idx_namespace, min, max, order) - .map(deserialize_kv::); - Box::new(mapped) - } - - pub fn range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - PK::Output: 'static, - { - self.no_prefix().range(store, min, max, order) - } - - pub fn keys<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - PK::Output: 'static, - { - self.no_prefix().keys(store, min, max, order) - } - - pub fn prefix(&self, p: IK::Prefix) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - &[], - |_, _, kv| deserialize_unique_kv::(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } - - pub fn sub_prefix(&self, p: IK::SubPrefix) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &p.prefix(), - &[], - |_, _, kv| deserialize_unique_kv::(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } - - fn no_prefix(&self) -> Prefix { - Prefix::with_deserialization_functions( - self.idx_namespace, - &[], - &[], - |_, _, kv| deserialize_unique_kv::(kv), - |_, _, kv| deserialize_unique_v(kv), - ) - } -} diff --git a/packages/storage-plus/src/int_key.rs b/packages/storage-plus/src/int_key.rs deleted file mode 100644 index 0292674a2..000000000 --- a/packages/storage-plus/src/int_key.rs +++ /dev/null @@ -1,130 +0,0 @@ -use std::mem; - -/// Our int keys are simply the big-endian representation bytes for unsigned ints, -/// but "sign-flipped" (xored msb) big-endian bytes for signed ints. -/// -/// So that the representation of signed integers is in the right lexicographical order. -pub trait IntKey: Sized + Copy { - type Buf: AsRef<[u8]> + AsMut<[u8]> + Into> + Default; - - fn to_cw_bytes(&self) -> Self::Buf; - fn from_cw_bytes(bytes: Self::Buf) -> Self; -} - -macro_rules! cw_uint_keys { - (for $($t:ty),+) => { - $(impl IntKey for $t { - type Buf = [u8; mem::size_of::<$t>()]; - - #[inline] - fn to_cw_bytes(&self) -> Self::Buf { - self.to_be_bytes() - } - - #[inline] - fn from_cw_bytes(bytes: Self::Buf) -> Self { - Self::from_be_bytes(bytes) - } - })* - } -} - -cw_uint_keys!(for u8, u16, u32, u64, u128); - -macro_rules! cw_int_keys { - (for $($t:ty, $ut:ty),+) => { - $(impl IntKey for $t { - type Buf = [u8; mem::size_of::<$t>()]; - - #[inline] - fn to_cw_bytes(&self) -> Self::Buf { - (*self as $ut ^ <$t>::MIN as $ut).to_be_bytes() - } - - #[inline] - fn from_cw_bytes(bytes: Self::Buf) -> Self { - (Self::from_be_bytes(bytes) as $ut ^ <$t>::MIN as $ut) as _ - } - })* - } -} - -cw_int_keys!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn x8_int_key_works() { - assert_eq!(0x42u8.to_cw_bytes(), [0x42]); - assert_eq!(0x42i8.to_cw_bytes(), [0xc2]); - assert_eq!((-0x3ei8).to_cw_bytes(), [0x42]); - } - - #[test] - fn x16_int_key_works() { - assert_eq!(0x4243u16.to_cw_bytes(), [0x42, 0x43]); - assert_eq!(0x4243i16.to_cw_bytes(), [0xc2, 0x43]); - assert_eq!((-0x3dbdi16).to_cw_bytes(), [0x42, 0x43]); - } - - #[test] - fn x32_int_key_works() { - assert_eq!(0x424344u32.to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]); - assert_eq!(0x424344i32.to_cw_bytes(), [0x80, 0x42, 0x43, 0x44]); - assert_eq!((-0x7fbdbcbci32).to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]); - } - - #[test] - fn x64_int_key_works() { - assert_eq!( - 0x42434445u64.to_cw_bytes(), - [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] - ); - assert_eq!( - 0x42434445i64.to_cw_bytes(), - [0x80, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] - ); - assert_eq!( - (-0x7fffffffbdbcbbbbi64).to_cw_bytes(), - [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45] - ); - } - - #[test] - fn x128_int_key_works() { - assert_eq!( - 0x4243444546u128.to_cw_bytes(), - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, - 0x45, 0x46 - ] - ); - assert_eq!( - 0x4243444546i128.to_cw_bytes(), - [ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, - 0x45, 0x46 - ] - ); - assert_eq!( - (-0x7fffffffffffffffffffffbdbcbbbabai128).to_cw_bytes(), - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, - 0x45, 0x46 - ] - ); - } - - #[test] - fn unsigned_int_key_order() { - assert!(0u32.to_cw_bytes() < 652u32.to_cw_bytes()); - } - - #[test] - fn signed_int_key_order() { - assert!((-321i32).to_cw_bytes() < 0i32.to_cw_bytes()); - assert!(0i32.to_cw_bytes() < 652i32.to_cw_bytes()); - } -} diff --git a/packages/storage-plus/src/item.rs b/packages/storage-plus/src/item.rs deleted file mode 100644 index 865fd534e..000000000 --- a/packages/storage-plus/src/item.rs +++ /dev/null @@ -1,319 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; -use std::marker::PhantomData; - -use cosmwasm_std::{ - to_vec, Addr, CustomQuery, QuerierWrapper, StdError, StdResult, Storage, WasmQuery, -}; - -use crate::helpers::{may_deserialize, must_deserialize}; - -/// Item stores one typed item at the given key. -/// This is an analog of Singleton. -/// It functions the same way as Path does but doesn't use a Vec and thus has a const fn constructor. -pub struct Item<'a, T> { - // this is full key - no need to length-prefix it, we only store one item - storage_key: &'a [u8], - // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed - data_type: PhantomData, -} - -impl<'a, T> Item<'a, T> { - pub const fn new(storage_key: &'a str) -> Self { - Item { - storage_key: storage_key.as_bytes(), - data_type: PhantomData, - } - } -} - -impl<'a, T> Item<'a, T> -where - T: Serialize + DeserializeOwned, -{ - // this gets the path of the data to use elsewhere - pub fn as_slice(&self) -> &[u8] { - self.storage_key - } - - /// save will serialize the model and store, returns an error on serialization issues - pub fn save(&self, store: &mut dyn Storage, data: &T) -> StdResult<()> { - store.set(self.storage_key, &to_vec(data)?); - Ok(()) - } - - pub fn remove(&self, store: &mut dyn Storage) { - store.remove(self.storage_key); - } - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage) -> StdResult { - let value = store.get(self.storage_key); - must_deserialize(&value) - } - - /// may_load will parse the data stored at the key if present, returns `Ok(None)` if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage) -> StdResult> { - let value = store.get(self.storage_key); - may_deserialize(&value) - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// It assumes, that data was initialized before, and if it doesn't exist, `Err(StdError::NotFound)` - /// is returned. - pub fn update(&self, store: &mut dyn Storage, action: A) -> Result - where - A: FnOnce(T) -> Result, - E: From, - { - let input = self.load(store)?; - let output = action(input)?; - self.save(store, &output)?; - Ok(output) - } - - /// If you import the proper Item from the remote contract, this will let you read the data - /// from a remote contract in a type-safe way using WasmQuery::RawQuery. - /// - /// Note that we expect an Item to be set, and error if there is no data there - pub fn query( - &self, - querier: &QuerierWrapper, - remote_contract: Addr, - ) -> StdResult { - let request = WasmQuery::Raw { - contract_addr: remote_contract.into(), - key: self.storage_key.into(), - }; - querier.query(&request.into()) - } -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::MockStorage; - use serde::{Deserialize, Serialize}; - - use cosmwasm_std::{OverflowError, OverflowOperation, StdError}; - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Config { - pub owner: String, - pub max_tokens: i32, - } - - // note const constructor rather than 2 funcs with Singleton - const CONFIG: Item = Item::new("config"); - - #[test] - fn save_and_load() { - let mut store = MockStorage::new(); - - assert!(CONFIG.load(&store).is_err()); - assert_eq!(CONFIG.may_load(&store).unwrap(), None); - - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - assert_eq!(cfg, CONFIG.load(&store).unwrap()); - } - - #[test] - fn remove_works() { - let mut store = MockStorage::new(); - - // store data - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - assert_eq!(cfg, CONFIG.load(&store).unwrap()); - - // remove it and loads None - CONFIG.remove(&mut store); - assert_eq!(None, CONFIG.may_load(&store).unwrap()); - - // safe to remove 2 times - CONFIG.remove(&mut store); - assert_eq!(None, CONFIG.may_load(&store).unwrap()); - } - - #[test] - fn isolated_reads() { - let mut store = MockStorage::new(); - - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - let reader = Item::::new("config"); - assert_eq!(cfg, reader.load(&store).unwrap()); - - let other_reader = Item::::new("config2"); - assert_eq!(other_reader.may_load(&store).unwrap(), None); - } - - #[test] - fn update_success() { - let mut store = MockStorage::new(); - - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - let output = CONFIG.update(&mut store, |mut c| -> StdResult<_> { - c.max_tokens *= 2; - Ok(c) - }); - let expected = Config { - owner: "admin".to_string(), - max_tokens: 2468, - }; - assert_eq!(output.unwrap(), expected); - assert_eq!(CONFIG.load(&store).unwrap(), expected); - } - - #[test] - fn update_can_change_variable_from_outer_scope() { - let mut store = MockStorage::new(); - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - let mut old_max_tokens = 0i32; - CONFIG - .update(&mut store, |mut c| -> StdResult<_> { - old_max_tokens = c.max_tokens; - c.max_tokens *= 2; - Ok(c) - }) - .unwrap(); - assert_eq!(old_max_tokens, 1234); - } - - #[test] - fn update_does_not_change_data_on_error() { - let mut store = MockStorage::new(); - - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - let output = CONFIG.update(&mut store, &|_c| { - Err(StdError::overflow(OverflowError::new( - OverflowOperation::Sub, - 4, - 7, - ))) - }); - match output.unwrap_err() { - StdError::Overflow { .. } => {} - err => panic!("Unexpected error: {:?}", err), - } - assert_eq!(CONFIG.load(&store).unwrap(), cfg); - } - - #[test] - fn update_supports_custom_errors() { - #[derive(Debug)] - enum MyError { - Std(StdError), - Foo, - } - - impl From for MyError { - fn from(original: StdError) -> MyError { - MyError::Std(original) - } - } - - let mut store = MockStorage::new(); - - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg).unwrap(); - - let res = CONFIG.update(&mut store, |mut c| { - if c.max_tokens > 5000 { - return Err(MyError::Foo); - } - if c.max_tokens > 20 { - return Err(StdError::generic_err("broken stuff").into()); // Uses Into to convert StdError to MyError - } - if c.max_tokens > 10 { - to_vec(&c)?; // Uses From to convert StdError to MyError - } - c.max_tokens += 20; - Ok(c) - }); - match res.unwrap_err() { - MyError::Std(StdError::GenericErr { .. }) => {} - err => panic!("Unexpected error: {:?}", err), - } - assert_eq!(CONFIG.load(&store).unwrap(), cfg); - } - - #[test] - fn readme_works() -> StdResult<()> { - let mut store = MockStorage::new(); - - // may_load returns Option, so None if data is missing - // load returns T and Err(StdError::NotFound{}) if data is missing - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - let cfg = Config { - owner: "admin".to_string(), - max_tokens: 1234, - }; - CONFIG.save(&mut store, &cfg)?; - let loaded = CONFIG.load(&store)?; - assert_eq!(cfg, loaded); - - // update an item with a closure (includes read and write) - // returns the newly saved value - let output = CONFIG.update(&mut store, |mut c| -> StdResult<_> { - c.max_tokens *= 2; - Ok(c) - })?; - assert_eq!(2468, output.max_tokens); - - // you can error in an update and nothing is saved - let failed = CONFIG.update(&mut store, |_| -> StdResult<_> { - Err(StdError::generic_err("failure mode")) - }); - assert!(failed.is_err()); - - // loading data will show the first update was saved - let loaded = CONFIG.load(&store)?; - let expected = Config { - owner: "admin".to_string(), - max_tokens: 2468, - }; - assert_eq!(expected, loaded); - - // we can remove data as well - CONFIG.remove(&mut store); - let empty = CONFIG.may_load(&store)?; - assert_eq!(None, empty); - - Ok(()) - } -} diff --git a/packages/storage-plus/src/iter_helpers.rs b/packages/storage-plus/src/iter_helpers.rs deleted file mode 100644 index fa9ad6641..000000000 --- a/packages/storage-plus/src/iter_helpers.rs +++ /dev/null @@ -1,222 +0,0 @@ -#![cfg(feature = "iterator")] - -use serde::de::DeserializeOwned; - -use cosmwasm_std::Record; -use cosmwasm_std::{from_slice, StdResult}; - -use crate::de::KeyDeserialize; -use crate::helpers::encode_length; - -#[allow(dead_code)] -pub(crate) fn deserialize_v(kv: Record) -> StdResult> { - let (k, v) = kv; - let t = from_slice::(&v)?; - Ok((k, t)) -} - -pub(crate) fn deserialize_kv( - kv: Record, -) -> StdResult<(K::Output, T)> { - let (k, v) = kv; - let kt = K::from_vec(k)?; - let vt = from_slice::(&v)?; - Ok((kt, vt)) -} - -/// Calculates the raw key prefix for a given namespace as documented -/// in https://github.com/webmaster128/key-namespacing#length-prefixed-keys -#[allow(dead_code)] -pub(crate) fn to_length_prefixed(namespace: &[u8]) -> Vec { - let mut out = Vec::with_capacity(namespace.len() + 2); - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); - out -} - -// TODO: add a check here that it is the real prefix? -#[inline] -pub(crate) fn trim(namespace: &[u8], key: &[u8]) -> Vec { - key[namespace.len()..].to_vec() -} - -#[inline] -pub(crate) fn concat(namespace: &[u8], key: &[u8]) -> Vec { - let mut k = namespace.to_vec(); - k.extend_from_slice(key); - k -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn to_length_prefixed_works() { - assert_eq!(to_length_prefixed(b""), b"\x00\x00"); - assert_eq!(to_length_prefixed(b"a"), b"\x00\x01a"); - assert_eq!(to_length_prefixed(b"ab"), b"\x00\x02ab"); - assert_eq!(to_length_prefixed(b"abc"), b"\x00\x03abc"); - } - - #[test] - fn to_length_prefixed_works_for_long_prefix() { - let long_namespace1 = vec![0; 256]; - let prefix1 = to_length_prefixed(&long_namespace1); - assert_eq!(prefix1.len(), 256 + 2); - assert_eq!(&prefix1[0..2], b"\x01\x00"); - - let long_namespace2 = vec![0; 30000]; - let prefix2 = to_length_prefixed(&long_namespace2); - assert_eq!(prefix2.len(), 30000 + 2); - assert_eq!(&prefix2[0..2], b"\x75\x30"); - - let long_namespace3 = vec![0; 0xFFFF]; - let prefix3 = to_length_prefixed(&long_namespace3); - assert_eq!(prefix3.len(), 0xFFFF + 2); - assert_eq!(&prefix3[0..2], b"\xFF\xFF"); - } - - #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] - fn to_length_prefixed_panics_for_too_long_prefix() { - let limit = 0xFFFF; - let long_namespace = vec![0; limit + 1]; - to_length_prefixed(&long_namespace); - } - - #[test] - fn to_length_prefixed_calculates_capacity_correctly() { - // Those tests cannot guarantee the required capacity was calculated correctly before - // the vector allocation but increase the likelyhood of a proper implementation. - - let key = to_length_prefixed(b""); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed(b"h"); - assert_eq!(key.capacity(), key.len()); - - let key = to_length_prefixed(b"hij"); - assert_eq!(key.capacity(), key.len()); - } -} - -// currently disabled tests as they require a bunch of legacy non-sense -// TODO: enable -#[cfg(test)] -#[cfg(not(feature = "iterator"))] -mod namespace_test { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn test_range() { - let mut storage = MockStorage::new(); - let prefix = to_length_prefixed(b"foo"); - let other_prefix = to_length_prefixed(b"food"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // ensure we get proper result from prefixed_range iterator - let mut iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); - let first = iter.next().unwrap(); - assert_eq!(first, (b"snowy".to_vec(), b"day".to_vec())); - let second = iter.next().unwrap(); - assert_eq!(second, (b"bar".to_vec(), b"none".to_vec())); - assert!(iter.next().is_none()); - - // ensure we get raw result from base range - let iter = storage.range(None, None, Order::Ascending); - assert_eq!(3, iter.count()); - - // foo comes first - let mut iter = storage.range(None, None, Order::Ascending); - let first = iter.next().unwrap(); - let expected_key = concat(&prefix, b"bar"); - assert_eq!(first, (expected_key, b"none".to_vec())); - } - - #[test] - fn test_range_with_prefix_wrapover() { - let mut storage = MockStorage::new(); - // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) - let prefix = to_length_prefixed(b"f\xff\xff"); - let other_prefix = to_length_prefixed(b"f\xff\x44"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // ensure we get proper result from prefixed_range iterator - let iter = range_with_prefix(&storage, &prefix, None, None, Order::Descending); - let elements: Vec = iter.collect(); - assert_eq!( - elements, - vec![ - (b"snowy".to_vec(), b"day".to_vec()), - (b"bar".to_vec(), b"none".to_vec()), - ] - ); - } - - #[test] - fn test_range_with_start_end_set() { - let mut storage = MockStorage::new(); - // if we don't properly wrap over there will be issues here (note 255+1 is used to calculate end) - let prefix = to_length_prefixed(b"f\xff\xff"); - let other_prefix = to_length_prefixed(b"f\xff\x44"); - - // set some values in this range - set_with_prefix(&mut storage, &prefix, b"bar", b"none"); - set_with_prefix(&mut storage, &prefix, b"snowy", b"day"); - - // set some values outside this range - set_with_prefix(&mut storage, &other_prefix, b"moon", b"buggy"); - - // make sure start and end are applied properly - let res: Vec = - range_with_prefix(&storage, &prefix, Some(b"b"), Some(b"c"), Order::Ascending) - .collect(); - assert_eq!(res.len(), 1); - assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); - - // make sure start and end are applied properly - let res: Vec = range_with_prefix( - &storage, - &prefix, - Some(b"bas"), - Some(b"sno"), - Order::Ascending, - ) - .collect(); - assert_eq!(res.len(), 0); - - let res: Vec = - range_with_prefix(&storage, &prefix, Some(b"ant"), None, Order::Ascending).collect(); - assert_eq!(res.len(), 2); - assert_eq!(res[0], (b"bar".to_vec(), b"none".to_vec())); - assert_eq!(res[1], (b"snowy".to_vec(), b"day".to_vec())); - } - - #[test] - fn test_namespace_upper_bound() { - assert_eq!(namespace_upper_bound(b"bob"), b"boc".to_vec()); - assert_eq!(namespace_upper_bound(b"fo\xfe"), b"fo\xff".to_vec()); - assert_eq!(namespace_upper_bound(b"fo\xff"), b"fp\x00".to_vec()); - // multiple \xff roll over - assert_eq!( - namespace_upper_bound(b"fo\xff\xff\xff"), - b"fp\x00\x00\x00".to_vec() - ); - // \xff not at the end are ignored - assert_eq!(namespace_upper_bound(b"\xffabc"), b"\xffabd".to_vec()); - } -} diff --git a/packages/storage-plus/src/keys.rs b/packages/storage-plus/src/keys.rs deleted file mode 100644 index cf7eff867..000000000 --- a/packages/storage-plus/src/keys.rs +++ /dev/null @@ -1,512 +0,0 @@ -use cosmwasm_std::Addr; - -use crate::de::KeyDeserialize; -use crate::helpers::namespaces_with_key; -use crate::int_key::IntKey; - -#[derive(Debug)] -pub enum Key<'a> { - Ref(&'a [u8]), - Val8([u8; 1]), - Val16([u8; 2]), - Val32([u8; 4]), - Val64([u8; 8]), - Val128([u8; 16]), -} - -impl<'a> AsRef<[u8]> for Key<'a> { - fn as_ref(&self) -> &[u8] { - match self { - Key::Ref(r) => r, - Key::Val8(v) => v, - Key::Val16(v) => v, - Key::Val32(v) => v, - Key::Val64(v) => v, - Key::Val128(v) => v, - } - } -} - -impl<'a> PartialEq<&[u8]> for Key<'a> { - fn eq(&self, other: &&[u8]) -> bool { - self.as_ref() == *other - } -} - -/// `PrimaryKey` needs to be implemented for types that want to be a `Map` (or `Map`-like) key, -/// or part of a key. -/// -/// In particular, it defines a series of types that help iterating over parts of a (composite) key: -/// -/// `Prefix`: Prefix is eager. That is, except for empty keys, it's always "one less" than the full key. -/// `Suffix`: Suffix is the complement of prefix. -/// `SubPrefix`: Sub-prefix is "one less" than prefix. -/// `SuperSuffix`: Super-suffix is "one more" than suffix. The complement of sub-prefix. -/// -/// By example, for a 2-tuple `(T, U)`: -/// -/// `T`: Prefix. -/// `U`: Suffix. -/// `()`: Sub-prefix. -/// `(T, U)`: Super-suffix. -/// -/// `SubPrefix` and `SuperSuffix` only make real sense in the case of triples. Still, they need to be -/// consistently defined for all types. -pub trait PrimaryKey<'a>: Clone { - /// These associated types need to implement `Prefixer`, so that they can be useful arguments - /// for `prefix()`, `sub_prefix()`, and their key-deserializable variants. - type Prefix: Prefixer<'a>; - type SubPrefix: Prefixer<'a>; - - /// These associated types need to implement `KeyDeserialize`, so that they can be returned from - /// `range_de()` and friends. - type Suffix: KeyDeserialize; - type SuperSuffix: KeyDeserialize; - - /// returns a slice of key steps, which can be optionally combined - fn key(&self) -> Vec; - - fn joined_key(&self) -> Vec { - let keys = self.key(); - let l = keys.len(); - namespaces_with_key( - &keys[0..l - 1].iter().map(Key::as_ref).collect::>(), - keys[l - 1].as_ref(), - ) - } - - fn joined_extra_key(&self, key: &[u8]) -> Vec { - let keys = self.key(); - namespaces_with_key(&keys.iter().map(Key::as_ref).collect::>(), key) - } -} - -// Empty / no primary key -impl<'a> PrimaryKey<'a> for () { - type Prefix = Self; - type SubPrefix = Self; - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - vec![] - } -} - -impl<'a> PrimaryKey<'a> for &'a [u8] { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self)] - } -} - -// Provide a string version of this to raw encode strings -impl<'a> PrimaryKey<'a> for &'a str { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self.as_bytes())] - } -} - -// use generics for combining there - so we can use &[u8], Vec, or IntKey -impl<'a, T: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, U: PrimaryKey<'a> + KeyDeserialize> - PrimaryKey<'a> for (T, U) -{ - type Prefix = T; - type SubPrefix = (); - type Suffix = U; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - let mut keys = self.0.key(); - keys.extend(self.1.key()); - keys - } -} - -// use generics for combining there - so we can use &[u8], Vec, or IntKey -impl< - 'a, - T: PrimaryKey<'a> + Prefixer<'a>, - U: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, - V: PrimaryKey<'a> + KeyDeserialize, - > PrimaryKey<'a> for (T, U, V) -{ - type Prefix = (T, U); - type SubPrefix = T; - type Suffix = V; - type SuperSuffix = (U, V); - - fn key(&self) -> Vec { - let mut keys = self.0.key(); - keys.extend(self.1.key()); - keys.extend(self.2.key()); - keys - } -} - -pub trait Prefixer<'a> { - /// returns 0 or more namespaces that should be length-prefixed and concatenated for range searches - fn prefix(&self) -> Vec; - - fn joined_prefix(&self) -> Vec { - let prefixes = self.prefix(); - namespaces_with_key(&prefixes.iter().map(Key::as_ref).collect::>(), &[]) - } -} - -impl<'a> Prefixer<'a> for () { - fn prefix(&self) -> Vec { - vec![] - } -} - -impl<'a> Prefixer<'a> for &'a [u8] { - fn prefix(&self) -> Vec { - vec![Key::Ref(self)] - } -} - -impl<'a, T: Prefixer<'a>, U: Prefixer<'a>> Prefixer<'a> for (T, U) { - fn prefix(&self) -> Vec { - let mut res = self.0.prefix(); - res.extend(self.1.prefix().into_iter()); - res - } -} - -impl<'a, T: Prefixer<'a>, U: Prefixer<'a>, V: Prefixer<'a>> Prefixer<'a> for (T, U, V) { - fn prefix(&self) -> Vec { - let mut res = self.0.prefix(); - res.extend(self.1.prefix().into_iter()); - res.extend(self.2.prefix().into_iter()); - res - } -} - -// Provide a string version of this to raw encode strings -impl<'a> Prefixer<'a> for &'a str { - fn prefix(&self) -> Vec { - vec![Key::Ref(self.as_bytes())] - } -} - -impl<'a> PrimaryKey<'a> for Vec { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - vec![Key::Ref(self)] - } -} - -impl<'a> Prefixer<'a> for Vec { - fn prefix(&self) -> Vec { - vec![Key::Ref(self.as_ref())] - } -} - -impl<'a> PrimaryKey<'a> for String { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - vec![Key::Ref(self.as_bytes())] - } -} - -impl<'a> Prefixer<'a> for String { - fn prefix(&self) -> Vec { - vec![Key::Ref(self.as_bytes())] - } -} - -/// type safe version to ensure address was validated before use. -impl<'a> PrimaryKey<'a> for &'a Addr { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self.as_ref().as_bytes())] - } -} - -impl<'a> Prefixer<'a> for &'a Addr { - fn prefix(&self) -> Vec { - vec![Key::Ref(self.as_bytes())] - } -} - -/// owned variant. -impl<'a> PrimaryKey<'a> for Addr { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is simple, we don't add more prefixes - vec![Key::Ref(self.as_bytes())] - } -} - -impl<'a> Prefixer<'a> for Addr { - fn prefix(&self) -> Vec { - vec![Key::Ref(self.as_bytes())] - } -} - -macro_rules! integer_key { - (for $($t:ty, $v:tt),+) => { - $(impl<'a> PrimaryKey<'a> for $t { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - vec![Key::$v(self.to_cw_bytes())] - } - })* - } -} - -integer_key!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128); - -macro_rules! integer_prefix { - (for $($t:ty, $v:tt),+) => { - $(impl<'a> Prefixer<'a> for $t { - fn prefix(&self) -> Vec { - vec![Key::$v(self.to_cw_bytes())] - } - })* - } -} - -integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128); - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn naked_8key_works() { - let k: u8 = 42u8; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(42u8.to_cw_bytes(), path[0].as_ref()); - - let k: i8 = 42i8; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(42i8.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn naked_16key_works() { - let k: u16 = 4242u16; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242u16.to_cw_bytes(), path[0].as_ref()); - - let k: i16 = 4242i16; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242i16.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn naked_32key_works() { - let k: u32 = 4242u32; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242u32.to_cw_bytes(), path[0].as_ref()); - - let k: i32 = 4242i32; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242i32.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn naked_64key_works() { - let k: u64 = 4242u64; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242u64.to_cw_bytes(), path[0].as_ref()); - - let k: i64 = 4242i64; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242i64.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn naked_128key_works() { - let k: u128 = 4242u128; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242u128.to_cw_bytes(), path[0].as_ref()); - - let k: i128 = 4242i128; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(4242i128.to_cw_bytes(), path[0].as_ref()); - } - - #[test] - fn str_key_works() { - type K<'a> = &'a str; - - let k: K = "hello"; - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(b"hello", path[0].as_ref()); - - let joined = k.joined_key(); - assert_eq!(joined, b"hello") - } - - #[test] - fn string_key_works() { - type K = String; - - let k: K = "hello".to_string(); - let path = k.key(); - assert_eq!(1, path.len()); - assert_eq!(b"hello", path[0].as_ref()); - - let joined = k.joined_key(); - assert_eq!(joined, b"hello") - } - - #[test] - fn nested_str_key_works() { - type K<'a> = (&'a str, &'a [u8]); - - let k: K = ("hello", b"world"); - let path = k.key(); - assert_eq!(2, path.len()); - assert_eq!(b"hello", path[0].as_ref()); - assert_eq!(b"world", path[1].as_ref()); - } - - #[test] - fn composite_byte_key() { - let k: (&[u8], &[u8]) = ("foo".as_bytes(), b"bar"); - let path = k.key(); - assert_eq!(2, path.len()); - assert_eq!(path, vec!["foo".as_bytes(), b"bar"],); - } - - #[test] - fn naked_composite_int_key() { - let k: (u32, u64) = (123, 87654); - let path = k.key(); - assert_eq!(2, path.len()); - assert_eq!(4, path[0].as_ref().len()); - assert_eq!(8, path[1].as_ref().len()); - assert_eq!(path[0].as_ref(), 123u32.to_cw_bytes()); - assert_eq!(path[1].as_ref(), 87654u64.to_cw_bytes()); - } - - #[test] - fn nested_composite_keys() { - // use this to ensure proper type-casts below - let first: &[u8] = b"foo"; - // this function tests how well the generics extend to "edge cases" - let k: ((&[u8], &[u8]), &[u8]) = ((first, b"bar"), b"zoom"); - let path = k.key(); - assert_eq!(3, path.len()); - assert_eq!(path, vec![first, b"bar", b"zoom"]); - - // ensure prefix also works - let dir = k.0.prefix(); - assert_eq!(2, dir.len()); - assert_eq!(dir, vec![first, b"bar"]); - } - - #[test] - fn naked_8bit_prefixes() { - let pair: (u8, &[u8]) = (123, b"random"); - let one: Vec = vec![123]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - - let pair: (i8, &[u8]) = (123, b"random"); - // Signed int keys are "sign-flipped" - let one: Vec = vec![123 ^ 0x80]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - } - - #[test] - fn naked_16bit_prefixes() { - let pair: (u16, &[u8]) = (12345, b"random"); - let one: Vec = vec![48, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - - let pair: (i16, &[u8]) = (12345, b"random"); - // Signed int keys are "sign-flipped" - let one: Vec = vec![48 ^ 0x80, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - } - - #[test] - fn naked_64bit_prefixes() { - let pair: (u64, &[u8]) = (12345, b"random"); - let one: Vec = vec![0, 0, 0, 0, 0, 0, 48, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - - let pair: (i64, &[u8]) = (12345, b"random"); - // Signed int keys are "sign-flipped" - #[allow(clippy::identity_op)] - let one: Vec = vec![0 ^ 0x80, 0, 0, 0, 0, 0, 48, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - } - - #[test] - fn naked_proper_prefixes() { - let pair: (u32, &[u8]) = (12345, b"random"); - let one: Vec = vec![0, 0, 48, 57]; - let two: Vec = b"random".to_vec(); - assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]); - - let triple: (&str, u32, &[u8]) = ("begin", 12345, b"end"); - let one: Vec = b"begin".to_vec(); - let two: Vec = vec![0, 0, 48, 57]; - let three: Vec = b"end".to_vec(); - assert_eq!( - triple.prefix(), - vec![one.as_slice(), two.as_slice(), three.as_slice()] - ); - - // same works with owned variants (&str -> String, &[u8] -> Vec) - let owned_triple: (String, u32, Vec) = ("begin".to_string(), 12345, b"end".to_vec()); - assert_eq!( - owned_triple.prefix(), - vec![one.as_slice(), two.as_slice(), three.as_slice()] - ); - } -} diff --git a/packages/storage-plus/src/lib.rs b/packages/storage-plus/src/lib.rs deleted file mode 100644 index a91f096a4..000000000 --- a/packages/storage-plus/src/lib.rs +++ /dev/null @@ -1,87 +0,0 @@ -/*! -After building `cosmwasm-storage`, we realized many of the design decisions were -limiting us and producing a lot of needless boilerplate. The decision was made to leave -those APIs stable for anyone wanting a very basic abstraction on the KV-store and to -build a much more powerful and complex ORM layer that can provide powerful accessors -using complex key types, which are transparently turned into bytes. - -This led to a number of breaking API changes in this package of the course of several -releases as we updated this with lots of experience, user feedback, and deep dives to harness -the full power of generics. - -For more information on this package, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/storage-plus/README.md). -*/ - -mod bound; -mod de; -mod deque; -mod endian; -mod helpers; -mod indexed_map; -mod indexed_snapshot; -mod indexes; -mod int_key; -mod item; -mod iter_helpers; -mod keys; -mod map; -mod path; -mod prefix; -mod snapshot; - -#[cfg(feature = "iterator")] -pub use bound::{Bound, Bounder, PrefixBound, RawBound}; -pub use de::KeyDeserialize; -pub use deque::Deque; -pub use deque::DequeIter; -pub use endian::Endian; -#[cfg(feature = "iterator")] -pub use indexed_map::{IndexList, IndexedMap}; -#[cfg(feature = "iterator")] -pub use indexed_snapshot::IndexedSnapshotMap; -#[cfg(feature = "iterator")] -pub use indexes::Index; -#[cfg(feature = "iterator")] -pub use indexes::MultiIndex; -#[cfg(feature = "iterator")] -pub use indexes::UniqueIndex; -pub use int_key::IntKey; -pub use item::Item; -pub use keys::{Key, Prefixer, PrimaryKey}; -pub use map::Map; -pub use path::Path; -#[cfg(feature = "iterator")] -pub use prefix::{range_with_prefix, Prefix}; -#[cfg(feature = "iterator")] -pub use snapshot::{SnapshotItem, SnapshotMap, Strategy}; - -// cw_storage_macro reexports -#[cfg(all(feature = "iterator", feature = "macro"))] -#[macro_use] -extern crate cw_storage_macro; -#[cfg(all(feature = "iterator", feature = "macro"))] -/// Auto generate an `IndexList` impl for your indexes struct. -/// -/// # Example -/// -/// ```rust -/// use cosmwasm_std::Addr; -/// use cw_storage_plus::{MultiIndex, UniqueIndex, index_list}; -/// use serde::{Serialize, Deserialize}; -/// -/// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -/// struct TestStruct { -/// id: u64, -/// id2: u32, -/// addr: Addr, -/// } -/// -/// #[index_list(TestStruct)] // <- Add this line right here. -/// struct TestIndexes<'a> { -/// id: MultiIndex<'a, u32, TestStruct, u64>, -/// addr: UniqueIndex<'a, Addr, TestStruct>, -/// } -/// ``` -/// -pub use cw_storage_macro::index_list; diff --git a/packages/storage-plus/src/map.rs b/packages/storage-plus/src/map.rs deleted file mode 100644 index 322cdeec7..000000000 --- a/packages/storage-plus/src/map.rs +++ /dev/null @@ -1,1580 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; -use std::marker::PhantomData; - -#[cfg(feature = "iterator")] -use crate::bound::{Bound, PrefixBound}; -#[cfg(feature = "iterator")] -use crate::de::KeyDeserialize; -use crate::helpers::query_raw; -#[cfg(feature = "iterator")] -use crate::iter_helpers::{deserialize_kv, deserialize_v}; -#[cfg(feature = "iterator")] -use crate::keys::Prefixer; -use crate::keys::{Key, PrimaryKey}; -use crate::path::Path; -#[cfg(feature = "iterator")] -use crate::prefix::{namespaced_prefix_range, Prefix}; -use cosmwasm_std::{from_slice, Addr, CustomQuery, QuerierWrapper, StdError, StdResult, Storage}; - -#[derive(Debug, Clone)] -pub struct Map<'a, K, T> { - namespace: &'a [u8], - // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed - key_type: PhantomData, - data_type: PhantomData, -} - -impl<'a, K, T> Map<'a, K, T> { - pub const fn new(namespace: &'a str) -> Self { - Map { - namespace: namespace.as_bytes(), - data_type: PhantomData, - key_type: PhantomData, - } - } - - pub fn namespace(&self) -> &'a [u8] { - self.namespace - } -} - -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a>, -{ - pub fn key(&self, k: K) -> Path { - Path::new( - self.namespace, - &k.key().iter().map(Key::as_ref).collect::>(), - ) - } - - #[cfg(feature = "iterator")] - pub(crate) fn no_prefix_raw(&self) -> Prefix, T, K> { - Prefix::new(self.namespace, &[]) - } - - pub fn save(&self, store: &mut dyn Storage, k: K, data: &T) -> StdResult<()> { - self.key(k).save(store, data) - } - - pub fn remove(&self, store: &mut dyn Storage, k: K) { - self.key(k).remove(store) - } - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage, k: K) -> StdResult { - self.key(k).load(store) - } - - /// may_load will parse the data stored at the key if present, returns Ok(None) if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage, k: K) -> StdResult> { - self.key(k).may_load(store) - } - - /// has returns true or false if any data is at this key, without parsing or interpreting the - /// contents. - pub fn has(&self, store: &dyn Storage, k: K) -> bool { - self.key(k).has(store) - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - pub fn update(&self, store: &mut dyn Storage, k: K, action: A) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - self.key(k).update(store, action) - } - - /// If you import the proper Map from the remote contract, this will let you read the data - /// from a remote contract in a type-safe way using WasmQuery::RawQuery - pub fn query( - &self, - querier: &QuerierWrapper, - remote_contract: Addr, - k: K, - ) -> StdResult> { - let key = self.key(k).storage_key.into(); - let result = query_raw(querier, remote_contract, key)?; - if result.is_empty() { - Ok(None) - } else { - from_slice(&result).map(Some) - } - } - - /// Clears the map, removing all elements. - #[cfg(feature = "iterator")] - pub fn clear(&self, store: &mut dyn Storage) { - const TAKE: usize = 10; - let mut cleared = false; - - while !cleared { - let paths = self - .no_prefix_raw() - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .map(|raw_key| Path::::new(self.namespace, &[raw_key.as_slice()])) - // Take just TAKE elements to prevent possible heap overflow if the Map is big. - .take(TAKE) - .collect::>(); - - paths.iter().for_each(|path| store.remove(path)); - - cleared = paths.len() < TAKE; - } - } - - /// Returns `true` if the map is empty. - #[cfg(feature = "iterator")] - pub fn is_empty(&self, store: &dyn Storage) -> bool { - self.no_prefix_raw() - .keys_raw(store, None, None, cosmwasm_std::Order::Ascending) - .next() - .is_none() - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a>, -{ - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { - Prefix::new(self.namespace, &p.prefix()) - } - - pub fn prefix(&self, p: K::Prefix) -> Prefix { - Prefix::new(self.namespace, &p.prefix()) - } -} - -// short-cut for simple keys, rather than .prefix(()).range_raw(...) -#[cfg(feature = "iterator")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - // TODO: this should only be when K::Prefix == () - // Other cases need to call prefix() first - K: PrimaryKey<'a>, -{ - /// While `range_raw` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range_raw` accepts bounds for the lowest and highest elements of the `Prefix` - /// itself, and iterates over those (inclusively or exclusively, depending on `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range_raw<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box>> + 'c> - where - T: 'c, - 'a: 'c, - { - let mapped = - namespaced_prefix_range(store, self.namespace, min, max, order).map(deserialize_v); - Box::new(mapped) - } -} - -#[cfg(feature = "iterator")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - K: 'c, - K::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.namespace, min, max, order) - .map(deserialize_kv::); - Box::new(mapped) - } - - 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>, -{ - 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")] -impl<'a, K, T> Map<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize, -{ - pub fn range<'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().range(store, min, max, order) - } - - pub fn keys<'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().keys(store, min, max, order) - } -} - -#[cfg(test)] -mod test { - use super::*; - use serde::{Deserialize, Serialize}; - use std::ops::Deref; - - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::to_binary; - use cosmwasm_std::StdError::InvalidUtf8; - #[cfg(feature = "iterator")] - use cosmwasm_std::{Order, StdResult}; - - #[cfg(feature = "iterator")] - use crate::bound::Bounder; - - use crate::int_key::IntKey; - - #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] - struct Data { - pub name: String, - pub age: i32, - } - - const PEOPLE: Map<&[u8], Data> = Map::new("people"); - #[cfg(feature = "iterator")] - const PEOPLE_STR_KEY: &str = "people2"; - #[cfg(feature = "iterator")] - const PEOPLE_STR: Map<&str, Data> = Map::new(PEOPLE_STR_KEY); - #[cfg(feature = "iterator")] - const PEOPLE_ID: Map = Map::new("people_id"); - #[cfg(feature = "iterator")] - const SIGNED_ID: Map = Map::new("signed_id"); - - const ALLOWANCE: Map<(&[u8], &[u8]), u64> = Map::new("allow"); - - const TRIPLE: Map<(&[u8], u8, &str), u64> = Map::new("triple"); - - #[test] - fn create_path() { - let path = PEOPLE.key(b"john"); - let key = path.deref(); - // this should be prefixed(people) || john - assert_eq!("people".len() + "john".len() + 2, key.len()); - assert_eq!(b"people".to_vec().as_slice(), &key[2..8]); - assert_eq!(b"john".to_vec().as_slice(), &key[8..]); - - let path = ALLOWANCE.key((b"john", b"maria")); - let key = path.deref(); - // this should be prefixed(allow) || prefixed(john) || maria - assert_eq!( - "allow".len() + "john".len() + "maria".len() + 2 * 2, - key.len() - ); - assert_eq!(b"allow".to_vec().as_slice(), &key[2..7]); - assert_eq!(b"john".to_vec().as_slice(), &key[9..13]); - assert_eq!(b"maria".to_vec().as_slice(), &key[13..]); - - let path = TRIPLE.key((b"john", 8u8, "pedro")); - let key = path.deref(); - // this should be prefixed(allow) || prefixed(john) || maria - assert_eq!( - "triple".len() + "john".len() + 1 + "pedro".len() + 2 * 3, - key.len() - ); - assert_eq!(b"triple".to_vec().as_slice(), &key[2..8]); - assert_eq!(b"john".to_vec().as_slice(), &key[10..14]); - assert_eq!(8u8.to_cw_bytes(), &key[16..17]); - assert_eq!(b"pedro".to_vec().as_slice(), &key[17..]); - } - - #[test] - fn save_and_load() { - let mut store = MockStorage::new(); - - // save and load on one key - let john = PEOPLE.key(b"john"); - let data = Data { - name: "John".to_string(), - age: 32, - }; - assert_eq!(None, john.may_load(&store).unwrap()); - john.save(&mut store, &data).unwrap(); - assert_eq!(data, john.load(&store).unwrap()); - - // nothing on another key - assert_eq!(None, PEOPLE.may_load(&store, b"jack").unwrap()); - - // same named path gets the data - assert_eq!(data, PEOPLE.load(&store, b"john").unwrap()); - - // removing leaves us empty - john.remove(&mut store); - assert_eq!(None, john.may_load(&store).unwrap()); - } - - #[test] - fn existence() { - let mut store = MockStorage::new(); - - // set data in proper format - let data = Data { - name: "John".to_string(), - age: 32, - }; - PEOPLE.save(&mut store, b"john", &data).unwrap(); - - // set and remove it - PEOPLE.save(&mut store, b"removed", &data).unwrap(); - PEOPLE.remove(&mut store, b"removed"); - - // invalid, but non-empty data - store.set(&PEOPLE.key(b"random"), b"random-data"); - - // any data, including invalid or empty is returned as "has" - assert!(PEOPLE.has(&store, b"john")); - assert!(PEOPLE.has(&store, b"random")); - - // if nothing was written, it is false - assert!(!PEOPLE.has(&store, b"never-writen")); - assert!(!PEOPLE.has(&store, b"removed")); - } - - #[test] - fn composite_keys() { - let mut store = MockStorage::new(); - - // save and load on a composite key - let allow = ALLOWANCE.key((b"owner", b"spender")); - assert_eq!(None, allow.may_load(&store).unwrap()); - allow.save(&mut store, &1234).unwrap(); - assert_eq!(1234, allow.load(&store).unwrap()); - - // not under other key - let different = ALLOWANCE.may_load(&store, (b"owners", b"pender")).unwrap(); - assert_eq!(None, different); - - // matches under a proper copy - let same = ALLOWANCE.load(&store, (b"owner", b"spender")).unwrap(); - assert_eq!(1234, same); - } - - #[test] - fn triple_keys() { - let mut store = MockStorage::new(); - - // save and load on a triple composite key - let triple = TRIPLE.key((b"owner", 10u8, "recipient")); - assert_eq!(None, triple.may_load(&store).unwrap()); - triple.save(&mut store, &1234).unwrap(); - assert_eq!(1234, triple.load(&store).unwrap()); - - // not under other key - let different = TRIPLE - .may_load(&store, (b"owners", 10u8, "ecipient")) - .unwrap(); - assert_eq!(None, different); - - // matches under a proper copy - let same = TRIPLE.load(&store, (b"owner", 10u8, "recipient")).unwrap(); - assert_eq!(1234, same); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_raw_simple_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_raw(&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_raw( - &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_raw( - &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 range_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.range(&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 - .range(&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 - .range(&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_key_broken_deserialization_errors() { - let mut store = MockStorage::new(); - - // save and load on three keys - let data = Data { - name: "John".to_string(), - age: 32, - }; - PEOPLE_STR.save(&mut store, "john", &data).unwrap(); - - let data2 = Data { - name: "Jim".to_string(), - age: 44, - }; - PEOPLE_STR.save(&mut store, "jim", &data2).unwrap(); - - let data3 = Data { - name: "Ada".to_string(), - age: 23, - }; - PEOPLE_STR.save(&mut store, "ada", &data3).unwrap(); - - // let's iterate! - let all: StdResult> = PEOPLE_STR - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(3, all.len()); - assert_eq!( - all, - vec![ - ("ada".to_string(), data3.clone()), - ("jim".to_string(), data2.clone()), - ("john".to_string(), data.clone()) - ] - ); - - // Manually add a broken key (invalid utf-8) - store.set( - &[ - [0u8, PEOPLE_STR_KEY.len() as u8].as_slice(), - PEOPLE_STR_KEY.as_bytes(), - b"\xddim", - ] - .concat(), - &to_binary(&data2).unwrap(), - ); - - // Let's try to iterate again! - let all: StdResult> = PEOPLE_STR - .range(&store, None, None, Order::Ascending) - .collect(); - assert!(all.is_err()); - assert!(matches!(all.unwrap_err(), InvalidUtf8 { .. })); - - // And the same with keys() - let all: StdResult> = PEOPLE_STR - .keys(&store, None, None, Order::Ascending) - .collect(); - assert!(all.is_err()); - assert!(matches!(all.unwrap_err(), InvalidUtf8 { .. })); - - // But range_raw still works - let all: StdResult> = PEOPLE_STR - .range_raw(&store, None, None, Order::Ascending) - .collect(); - - let all = all.unwrap(); - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - (b"ada".to_vec(), data3.clone()), - (b"jim".to_vec(), data2.clone()), - (b"john".to_vec(), data.clone()), - (b"\xddim".to_vec(), data2.clone()), - ] - ); - - // And the same with keys_raw - let all: Vec<_> = PEOPLE_STR - .keys_raw(&store, None, None, Order::Ascending) - .collect(); - - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - b"ada".to_vec(), - b"jim".to_vec(), - b"john".to_vec(), - b"\xddim".to_vec(), - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_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 - .range(&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 - .range( - &store, - Some(Bound::inclusive(56u32)), - 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 - .range( - &store, - Some(Bound::inclusive(57u32)), - None, - Order::Ascending, - ) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(1234, data)]); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_simple_integer_key_with_bounder_trait() { - 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 - .range(&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 - .range(&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 - .range(&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")] - fn range_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 - .range(&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 - .range( - &store, - Some(Bound::inclusive(-56i32)), - 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 - .range( - &store, - Some(Bound::inclusive(-55i32)), - Some(Bound::inclusive(50i32)), - Order::Descending, - ) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(50, data3)]); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_simple_signed_integer_key_with_bounder_trait() { - 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 - .range(&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 - .range(&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 - .range( - &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_raw_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_raw(&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()).joined_key(), 1000), - ((b"owner".to_vec(), b"spender2".to_vec()).joined_key(), 3000), - ((b"owner2".to_vec(), b"spender".to_vec()).joined_key(), 5000), - ] - ); - - // let's try to iterate over a prefix - let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range_raw(&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)] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_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 - .prefix(b"owner") - .range(&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") - .range(&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() { - let mut store = MockStorage::new(); - - // save and load on three keys, one under different owner - TRIPLE - .save(&mut store, (b"owner", 9, "recipient"), &1000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner", 9, "recipient2"), &3000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner", 10, "recipient3"), &3000) - .unwrap(); - TRIPLE - .save(&mut store, (b"owner2", 9, "recipient"), &5000) - .unwrap(); - - // let's try to iterate! - let all: StdResult> = TRIPLE - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - ( - (b"owner".to_vec(), 9u8, b"recipient".to_vec()).joined_key(), - 1000 - ), - ( - (b"owner".to_vec(), 9u8, b"recipient2".to_vec()).joined_key(), - 3000 - ), - ( - (b"owner".to_vec(), 10u8, b"recipient3".to_vec()).joined_key(), - 3000 - ), - ( - (b"owner2".to_vec(), 9u8, b"recipient".to_vec()).joined_key(), - 5000 - ) - ] - ); - - // let's iterate over a prefix - let all: StdResult> = TRIPLE - .prefix((b"owner", 9)) - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - (b"recipient".to_vec(), 1000), - (b"recipient2".to_vec(), 3000) - ] - ); - - // let's iterate over a sub prefix - let all: StdResult> = TRIPLE - .sub_prefix(b"owner") - .range_raw(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(3, all.len()); - // Use range() if you want key deserialization - assert_eq!( - all, - vec![ - ((9u8, b"recipient".to_vec()).joined_key(), 1000), - ((9u8, b"recipient2".to_vec()).joined_key(), 3000), - ((10u8, b"recipient3".to_vec()).joined_key(), 3000) - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_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 - .prefix((b"owner", 9)) - .range( - &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)) - .range( - &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(); - - let add_ten = |a: Option| -> StdResult<_> { Ok(a.unwrap_or_default() + 10) }; - - // save and load on three keys, one under different owner - let key: (&[u8], &[u8]) = (b"owner", b"spender"); - ALLOWANCE.update(&mut store, key, add_ten).unwrap(); - let twenty = ALLOWANCE.update(&mut store, key, add_ten).unwrap(); - assert_eq!(20, twenty); - let loaded = ALLOWANCE.load(&store, key).unwrap(); - assert_eq!(20, loaded); - } - - #[test] - fn readme_works() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // load and save with extra key argument - let empty = PEOPLE.may_load(&store, b"john")?; - assert_eq!(None, empty); - PEOPLE.save(&mut store, b"john", &data)?; - let loaded = PEOPLE.load(&store, b"john")?; - assert_eq!(data, loaded); - - // nothing on another key - let missing = PEOPLE.may_load(&store, b"jack")?; - assert_eq!(None, missing); - - // update function for new or existing keys - let birthday = |d: Option| -> StdResult { - match d { - Some(one) => Ok(Data { - name: one.name, - age: one.age + 1, - }), - None => Ok(Data { - name: "Newborn".to_string(), - age: 0, - }), - } - }; - - let old_john = PEOPLE.update(&mut store, b"john", birthday)?; - assert_eq!(33, old_john.age); - assert_eq!("John", old_john.name.as_str()); - - let new_jack = PEOPLE.update(&mut store, b"jack", birthday)?; - assert_eq!(0, new_jack.age); - assert_eq!("Newborn", new_jack.name.as_str()); - - // update also changes the store - assert_eq!(old_john, PEOPLE.load(&store, b"john")?); - assert_eq!(new_jack, PEOPLE.load(&store, b"jack")?); - - // removing leaves us empty - PEOPLE.remove(&mut store, b"john"); - let empty = PEOPLE.may_load(&store, b"john")?; - assert_eq!(None, empty); - - Ok(()) - } - - #[test] - fn readme_works_composite_keys() -> StdResult<()> { - let mut store = MockStorage::new(); - - // save and load on a composite key - let empty = ALLOWANCE.may_load(&store, (b"owner", b"spender"))?; - assert_eq!(None, empty); - ALLOWANCE.save(&mut store, (b"owner", b"spender"), &777)?; - let loaded = ALLOWANCE.load(&store, (b"owner", b"spender"))?; - assert_eq!(777, loaded); - - // doesn't appear under other key (even if a concat would be the same) - let different = ALLOWANCE.may_load(&store, (b"owners", b"pender")).unwrap(); - assert_eq!(None, different); - - // simple update - ALLOWANCE.update(&mut store, (b"owner", b"spender"), |v| -> StdResult { - Ok(v.unwrap_or_default() + 222) - })?; - let loaded = ALLOWANCE.load(&store, (b"owner", b"spender"))?; - assert_eq!(999, loaded); - - Ok(()) - } - - #[test] - fn readme_works_with_path() -> StdResult<()> { - let mut store = MockStorage::new(); - let data = Data { - name: "John".to_string(), - age: 32, - }; - - // create a Path one time to use below - let john = PEOPLE.key(b"john"); - - // Use this just like an Item above - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - john.save(&mut store, &data)?; - let loaded = john.load(&store)?; - assert_eq!(data, loaded); - john.remove(&mut store); - let empty = john.may_load(&store)?; - assert_eq!(None, empty); - - // same for composite keys, just use both parts in key() - let allow = ALLOWANCE.key((b"owner", b"spender")); - allow.save(&mut store, &1234)?; - let loaded = allow.load(&store)?; - assert_eq!(1234, loaded); - allow.update(&mut store, |x| -> StdResult { - Ok(x.unwrap_or_default() * 2) - })?; - let loaded = allow.load(&store)?; - assert_eq!(2468, loaded); - - Ok(()) - } - - #[test] - #[cfg(feature = "iterator")] - fn readme_with_range_raw() -> StdResult<()> { - 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)?; - let data2 = Data { - name: "Jim".to_string(), - age: 44, - }; - PEOPLE.save(&mut store, b"jim", &data2)?; - - // iterate over them all - let all: StdResult> = PEOPLE - .range_raw(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())] - ); - - // or just show what is after jim - let all: StdResult> = PEOPLE - .range_raw( - &store, - Some(Bound::exclusive(b"jim" as &[u8])), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(all?, vec![(b"john".to_vec(), data)]); - - // save and load on three keys, one under different owner - ALLOWANCE.save(&mut store, (b"owner", b"spender"), &1000)?; - ALLOWANCE.save(&mut store, (b"owner", b"spender2"), &3000)?; - ALLOWANCE.save(&mut store, (b"owner2", b"spender"), &5000)?; - - // get all under one key - let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range_raw(&store, None, None, Order::Ascending) - .collect(); - assert_eq!( - all?, - vec![(b"spender".to_vec(), 1000), (b"spender2".to_vec(), 3000)] - ); - - // Or ranges between two items (even reverse) - let all: StdResult> = ALLOWANCE - .prefix(b"owner") - .range_raw( - &store, - Some(Bound::exclusive(b"spender1" as &[u8])), - Some(Bound::inclusive(b"spender2" as &[u8])), - Order::Descending, - ) - .collect(); - assert_eq!(all?, vec![(b"spender2".to_vec(), 3000)]); - - Ok(()) - } - - #[test] - #[cfg(feature = "iterator")] - fn prefixed_range_raw_works() { - // this is designed to look as much like a secondary index as possible - // we want to query over a range of u32 for the first key and all subkeys - const AGES: Map<(u32, Vec), u64> = Map::new("ages"); - - let mut store = MockStorage::new(); - AGES.save(&mut store, (2, vec![1, 2, 3]), &123).unwrap(); - AGES.save(&mut store, (3, vec![4, 5, 6]), &456).unwrap(); - AGES.save(&mut store, (5, vec![7, 8, 9]), &789).unwrap(); - AGES.save(&mut store, (5, vec![9, 8, 7]), &987).unwrap(); - AGES.save(&mut store, (7, vec![20, 21, 22]), &2002).unwrap(); - AGES.save(&mut store, (8, vec![23, 24, 25]), &2332).unwrap(); - - // typical range under one prefix as a control - let fives = AGES - .prefix(5) - .range_raw(&store, None, None, Order::Ascending) - .collect::>>() - .unwrap(); - assert_eq!(fives.len(), 2); - assert_eq!(fives, vec![(vec![7, 8, 9], 789), (vec![9, 8, 7], 987)]); - - let keys: Vec<_> = AGES - .keys_raw(&store, None, None, Order::Ascending) - .collect(); - println!("keys: {:?}", keys); - - // using inclusive bounds both sides - let include = AGES - .prefix_range_raw( - &store, - Some(PrefixBound::inclusive(3u32)), - Some(PrefixBound::inclusive(7u32)), - Order::Ascending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 4); - assert_eq!(include, vec![456, 789, 987, 2002]); - - // using exclusive bounds both sides - let exclude = AGES - .prefix_range_raw( - &store, - Some(PrefixBound::exclusive(3u32)), - Some(PrefixBound::exclusive(7u32)), - Order::Ascending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(exclude.len(), 2); - assert_eq!(exclude, vec![789, 987]); - - // using inclusive in descending - let include = AGES - .prefix_range_raw( - &store, - Some(PrefixBound::inclusive(3u32)), - Some(PrefixBound::inclusive(5u32)), - Order::Descending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 3); - assert_eq!(include, vec![987, 789, 456]); - - // using exclusive in descending - let include = AGES - .prefix_range_raw( - &store, - Some(PrefixBound::exclusive(2u32)), - Some(PrefixBound::exclusive(5u32)), - Order::Descending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 1); - assert_eq!(include, vec![456]); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefixed_range_works() { - // this is designed to look as much like a secondary index as possible - // we want to query over a range of u32 for the first key and all subkeys - const AGES: Map<(u32, &str), u64> = Map::new("ages"); - - let mut store = MockStorage::new(); - AGES.save(&mut store, (2, "123"), &123).unwrap(); - AGES.save(&mut store, (3, "456"), &456).unwrap(); - AGES.save(&mut store, (5, "789"), &789).unwrap(); - AGES.save(&mut store, (5, "987"), &987).unwrap(); - AGES.save(&mut store, (7, "202122"), &2002).unwrap(); - AGES.save(&mut store, (8, "232425"), &2332).unwrap(); - - // typical range under one prefix as a control - let fives = AGES - .prefix(5) - .range(&store, None, None, Order::Ascending) - .collect::>>() - .unwrap(); - assert_eq!(fives.len(), 2); - assert_eq!( - fives, - vec![("789".to_string(), 789), ("987".to_string(), 987)] - ); - - let keys: Vec<_> = AGES.keys(&store, None, None, Order::Ascending).collect(); - println!("keys: {:?}", keys); - - // using inclusive bounds both sides - let include = AGES - .prefix_range( - &store, - Some(PrefixBound::inclusive(3u32)), - Some(PrefixBound::inclusive(7u32)), - Order::Ascending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 4); - assert_eq!(include, vec![456, 789, 987, 2002]); - - // using exclusive bounds both sides - let exclude = AGES - .prefix_range( - &store, - Some(PrefixBound::exclusive(3u32)), - Some(PrefixBound::exclusive(7u32)), - Order::Ascending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(exclude.len(), 2); - assert_eq!(exclude, vec![789, 987]); - - // using inclusive in descending - let include = AGES - .prefix_range( - &store, - Some(PrefixBound::inclusive(3u32)), - Some(PrefixBound::inclusive(5u32)), - Order::Descending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 3); - assert_eq!(include, vec![987, 789, 456]); - - // using exclusive in descending - let include = AGES - .prefix_range( - &store, - Some(PrefixBound::exclusive(2u32)), - Some(PrefixBound::exclusive(5u32)), - Order::Descending, - ) - .map(|r| r.map(|(_, v)| v)) - .collect::>>() - .unwrap(); - assert_eq!(include.len(), 1); - assert_eq!(include, vec![456]); - } - - #[test] - #[cfg(feature = "iterator")] - fn clear_works() { - const TEST_MAP: Map<&str, u32> = Map::new("test_map"); - - let mut storage = MockStorage::new(); - TEST_MAP.save(&mut storage, "key0", &0u32).unwrap(); - TEST_MAP.save(&mut storage, "key1", &1u32).unwrap(); - TEST_MAP.save(&mut storage, "key2", &2u32).unwrap(); - TEST_MAP.save(&mut storage, "key3", &3u32).unwrap(); - TEST_MAP.save(&mut storage, "key4", &4u32).unwrap(); - - TEST_MAP.clear(&mut storage); - - assert!(!TEST_MAP.has(&storage, "key0")); - assert!(!TEST_MAP.has(&storage, "key1")); - assert!(!TEST_MAP.has(&storage, "key2")); - assert!(!TEST_MAP.has(&storage, "key3")); - assert!(!TEST_MAP.has(&storage, "key4")); - } - - #[test] - #[cfg(feature = "iterator")] - fn is_empty_works() { - const TEST_MAP: Map<&str, u32> = Map::new("test_map"); - - let mut storage = MockStorage::new(); - - assert!(TEST_MAP.is_empty(&storage)); - - TEST_MAP.save(&mut storage, "key1", &1u32).unwrap(); - TEST_MAP.save(&mut storage, "key2", &2u32).unwrap(); - - assert!(!TEST_MAP.is_empty(&storage)); - } -} diff --git a/packages/storage-plus/src/path.rs b/packages/storage-plus/src/path.rs deleted file mode 100644 index e6a3cb526..000000000 --- a/packages/storage-plus/src/path.rs +++ /dev/null @@ -1,96 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; -use std::marker::PhantomData; - -use crate::helpers::{may_deserialize, must_deserialize, nested_namespaces_with_key}; -use crate::keys::Key; -use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; -use std::ops::Deref; - -#[derive(Debug, Clone)] -pub struct Path -where - T: Serialize + DeserializeOwned, -{ - /// all namespaces prefixes and concatenated with the key - pub(crate) storage_key: Vec, - // see https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters for why this is needed - data: PhantomData, -} - -impl Deref for Path -where - T: Serialize + DeserializeOwned, -{ - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.storage_key - } -} - -impl Path -where - T: Serialize + DeserializeOwned, -{ - pub fn new(namespace: &[u8], keys: &[&[u8]]) -> Self { - let l = keys.len(); - // FIXME: make this more efficient - let storage_key = nested_namespaces_with_key( - &[namespace], - &keys[0..l - 1] - .iter() - .map(|k| Key::Ref(k)) - .collect::>(), - keys[l - 1], - ); - Path { - storage_key, - data: PhantomData, - } - } - - /// save will serialize the model and store, returns an error on serialization issues - pub fn save(&self, store: &mut dyn Storage, data: &T) -> StdResult<()> { - store.set(&self.storage_key, &to_vec(data)?); - Ok(()) - } - - pub fn remove(&self, store: &mut dyn Storage) { - store.remove(&self.storage_key); - } - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage) -> StdResult { - let value = store.get(&self.storage_key); - must_deserialize(&value) - } - - /// may_load will parse the data stored at the key if present, returns Ok(None) if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage) -> StdResult> { - let value = store.get(&self.storage_key); - may_deserialize(&value) - } - - /// has returns true or false if any data is at this key, without parsing or interpreting the - /// contents. It will returns true for an length-0 byte array (Some(b"")), if you somehow manage to set that. - pub fn has(&self, store: &dyn Storage) -> bool { - store.get(&self.storage_key).is_some() - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - pub fn update(&self, store: &mut dyn Storage, action: A) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - let input = self.may_load(store)?; - let output = action(input)?; - self.save(store, &output)?; - Ok(output) - } -} diff --git a/packages/storage-plus/src/prefix.rs b/packages/storage-plus/src/prefix.rs deleted file mode 100644 index 6922226e8..000000000 --- a/packages/storage-plus/src/prefix.rs +++ /dev/null @@ -1,441 +0,0 @@ -#![cfg(feature = "iterator")] -use serde::de::DeserializeOwned; -use serde::Serialize; -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::{Bound, Prefixer, PrimaryKey}; - -type DeserializeVFn = fn(&dyn Storage, &[u8], Record) -> StdResult>; - -type DeserializeKvFn = - fn(&dyn Storage, &[u8], Record) -> StdResult<(::Output, T)>; - -pub fn default_deserializer_v( - _: &dyn Storage, - _: &[u8], - raw: Record, -) -> StdResult> { - deserialize_v(raw) -} - -pub fn default_deserializer_kv( - _: &dyn Storage, - _: &[u8], - raw: Record, -) -> StdResult<(K::Output, T)> { - deserialize_kv::(raw) -} - -#[derive(Clone)] -pub struct Prefix> -where - K: KeyDeserialize, - T: Serialize + DeserializeOwned, -{ - /// 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<(T, B)>, - pk_name: Vec, - de_fn_kv: DeserializeKvFn, - de_fn_v: DeserializeVFn, -} - -impl Deref for Prefix -where - K: KeyDeserialize, - T: Serialize + DeserializeOwned, -{ - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.storage_prefix - } -} - -impl Prefix -where - K: KeyDeserialize, - T: Serialize + DeserializeOwned, -{ - pub fn new(top_name: &[u8], sub_names: &[Key]) -> Self { - Prefix::with_deserialization_functions( - top_name, - sub_names, - &[], - default_deserializer_kv::, - default_deserializer_v, - ) - } - - pub fn with_deserialization_functions( - top_name: &[u8], - sub_names: &[Key], - pk_name: &[u8], - de_fn_kv: DeserializeKvFn, - de_fn_v: DeserializeVFn, - ) -> Self { - let storage_prefix = nested_namespaces_with_key(&[top_name], sub_names, b""); - Prefix { - storage_prefix, - data: PhantomData, - pk_name: pk_name.to_vec(), - de_fn_kv, - 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>, - 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_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>, - order: Order, - ) -> Box> + 'a> { - 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>, - 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_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<'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_raw_bound()), - max.map(|b| b.to_raw_bound()), - order, - ) - .map(move |kv| (de_fn)(store, &pk_name, kv).map(|(k, _)| k)); - Box::new(mapped) - } -} - -pub fn range_with_prefix<'a>( - storage: &'a dyn Storage, - namespace: &[u8], - start: Option, - end: Option, - order: Order, -) -> Box + 'a> { - 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); - - // make a copy for the closure to handle lifetimes safely - let prefix = namespace.to_vec(); - let mapped = base_iterator.map(move |(k, v)| (trim(&prefix, &k), v)); - Box::new(mapped) -} - -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(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 { - match bound { - None => increment_last_byte(namespace), - // this is the natural limits of the underlying Storage - Some(RawBound::Exclusive(limit)) => concat(namespace, &limit), - Some(RawBound::Inclusive(limit)) => concat(namespace, &extend_one_byte(&limit)), - } -} - -pub fn namespaced_prefix_range<'a, 'c, K: Prefixer<'a>>( - storage: &'c dyn Storage, - namespace: &[u8], - start: Option>, - end: Option>, - order: Order, -) -> Box + 'c> { - let prefix = namespaces_with_key(&[namespace], &[]); - let start = calc_prefix_start_bound(&prefix, start); - let end = calc_prefix_end_bound(&prefix, end); - - // get iterator from storage - let base_iterator = storage.range(Some(&start), Some(&end), order); - - // make a copy for the closure to handle lifetimes safely - let mapped = base_iterator.map(move |(k, v)| (trim(&prefix, &k), v)); - Box::new(mapped) -} - -fn calc_prefix_start_bound<'a, K: Prefixer<'a>>( - namespace: &[u8], - bound: Option>, -) -> Vec { - match bound.map(|b| b.to_raw_bound()) { - None => namespace.to_vec(), - // this is the natural limits of the underlying Storage - Some(RawBound::Inclusive(limit)) => concat(namespace, &limit), - Some(RawBound::Exclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), - } -} - -fn calc_prefix_end_bound<'a, K: Prefixer<'a>>( - namespace: &[u8], - bound: Option>, -) -> Vec { - match bound.map(|b| b.to_raw_bound()) { - None => increment_last_byte(namespace), - // this is the natural limits of the underlying Storage - Some(RawBound::Exclusive(limit)) => concat(namespace, &limit), - Some(RawBound::Inclusive(limit)) => concat(namespace, &increment_last_byte(&limit)), - } -} - -fn extend_one_byte(limit: &[u8]) -> Vec { - let mut v = limit.to_vec(); - v.push(0); - v -} - -/// Returns a new vec of same length and last byte incremented by one -/// If last bytes are 255, we handle overflow up the chain. -/// If all bytes are 255, this returns wrong data - but that is never possible as a namespace -fn increment_last_byte(input: &[u8]) -> Vec { - let mut copy = input.to_vec(); - // zero out all trailing 255, increment first that is not such - for i in (0..input.len()).rev() { - if copy[i] == 255 { - copy[i] = 0; - } else { - copy[i] += 1; - break; - } - } - copy -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn ensure_proper_range_bounds() { - let mut store = MockStorage::new(); - // manually create this - not testing nested prefixes here - let prefix: Prefix, u64> = Prefix { - storage_prefix: b"foo".to_vec(), - data: PhantomData::<(u64, _)>, - pk_name: vec![], - de_fn_kv: |_, _, kv| deserialize_kv::, u64>(kv), - de_fn_v: |_, _, kv| deserialize_v(kv), - }; - - // set some data, we care about "foo" prefix - store.set(b"foobar", b"1"); - store.set(b"foora", b"2"); - store.set(b"foozi", b"3"); - // these shouldn't match - store.set(b"foply", b"100"); - store.set(b"font", b"200"); - - let expected = vec![ - (b"bar".to_vec(), 1u64), - (b"ra".to_vec(), 2u64), - (b"zi".to_vec(), 3u64), - ]; - let expected_reversed: Vec<(Vec, u64)> = expected.iter().rev().cloned().collect(); - - // let's do the basic sanity check - let res: StdResult> = prefix - .range_raw(&store, None, None, Order::Ascending) - .collect(); - assert_eq!(&expected, &res.unwrap()); - let res: StdResult> = prefix - .range_raw(&store, None, None, Order::Descending) - .collect(); - assert_eq!(&expected_reversed, &res.unwrap()); - - // now let's check some ascending ranges - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::inclusive(b"ra".to_vec())), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(&expected[1..], res.unwrap().as_slice()); - // skip excluded - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::exclusive(b"ra".to_vec())), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(&expected[2..], res.unwrap().as_slice()); - // if we exclude something a little lower, we get matched - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::exclusive(b"r".to_vec())), - None, - Order::Ascending, - ) - .collect(); - assert_eq!(&expected[1..], res.unwrap().as_slice()); - - // now let's check some descending ranges - let res: StdResult> = prefix - .range_raw( - &store, - None, - Some(Bound::inclusive(b"ra".to_vec())), - Order::Descending, - ) - .collect(); - assert_eq!(&expected_reversed[1..], res.unwrap().as_slice()); - // skip excluded - let res: StdResult> = prefix - .range_raw( - &store, - None, - Some(Bound::exclusive(b"ra".to_vec())), - Order::Descending, - ) - .collect(); - assert_eq!(&expected_reversed[2..], res.unwrap().as_slice()); - // if we exclude something a little higher, we get matched - let res: StdResult> = prefix - .range_raw( - &store, - None, - Some(Bound::exclusive(b"rb".to_vec())), - Order::Descending, - ) - .collect(); - assert_eq!(&expected_reversed[1..], res.unwrap().as_slice()); - - // now test when both sides are set - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::inclusive(b"ra".to_vec())), - Some(Bound::exclusive(b"zi".to_vec())), - Order::Ascending, - ) - .collect(); - assert_eq!(&expected[1..2], res.unwrap().as_slice()); - // and descending - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::inclusive(b"ra".to_vec())), - Some(Bound::exclusive(b"zi".to_vec())), - Order::Descending, - ) - .collect(); - assert_eq!(&expected[1..2], res.unwrap().as_slice()); - // Include both sides - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::inclusive(b"ra".to_vec())), - Some(Bound::inclusive(b"zi".to_vec())), - Order::Descending, - ) - .collect(); - assert_eq!(&expected_reversed[..2], res.unwrap().as_slice()); - // Exclude both sides - let res: StdResult> = prefix - .range_raw( - &store, - Some(Bound::exclusive(b"ra".to_vec())), - Some(Bound::exclusive(b"zi".to_vec())), - Order::Ascending, - ) - .collect(); - assert_eq!(res.unwrap().as_slice(), &[]); - } -} diff --git a/packages/storage-plus/src/snapshot/item.rs b/packages/storage-plus/src/snapshot/item.rs deleted file mode 100644 index 633f073ff..000000000 --- a/packages/storage-plus/src/snapshot/item.rs +++ /dev/null @@ -1,325 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; - -use cosmwasm_std::{StdError, StdResult, Storage}; - -use crate::snapshot::{ChangeSet, Snapshot}; -use crate::{Item, Map, Strategy}; - -/// Item that maintains a snapshot of one or more checkpoints. -/// We can query historical data as well as current state. -/// What data is snapshotted depends on the Strategy. -pub struct SnapshotItem<'a, T> { - primary: Item<'a, T>, - changelog_namespace: &'a str, - snapshots: Snapshot<'a, (), T>, -} - -impl<'a, T> SnapshotItem<'a, T> { - /// Example: - /// - /// ```rust - /// use cw_storage_plus::{SnapshotItem, Strategy}; - /// - /// SnapshotItem::<'static, u64>::new( - /// "every", - /// "every__check", - /// "every__change", - /// Strategy::EveryBlock); - /// ``` - pub const fn new( - storage_key: &'a str, - checkpoints: &'a str, - changelog: &'a str, - strategy: Strategy, - ) -> Self { - SnapshotItem { - primary: Item::new(storage_key), - changelog_namespace: changelog, - snapshots: Snapshot::new(checkpoints, changelog, strategy), - } - } - - pub fn add_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.add_checkpoint(store, height) - } - - pub fn remove_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.remove_checkpoint(store, height) - } - - pub fn changelog(&self) -> Map> { - // Build and return a compatible Map with the proper key type - Map::new(self.changelog_namespace) - } -} - -impl<'a, T> SnapshotItem<'a, T> -where - T: Serialize + DeserializeOwned + Clone, -{ - /// load old value and store changelog - fn write_change(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - // if there is already data in the changelog for this block, do not write more - if self.snapshots.has_changelog(store, (), height)? { - return Ok(()); - } - // otherwise, store the previous value - let old = self.primary.may_load(store)?; - self.snapshots.write_changelog(store, (), height, old) - } - - pub fn save(&self, store: &mut dyn Storage, data: &T, height: u64) -> StdResult<()> { - if self.snapshots.should_checkpoint(store, &())? { - self.write_change(store, height)?; - } - self.primary.save(store, data) - } - - pub fn remove(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - if self.snapshots.should_checkpoint(store, &())? { - self.write_change(store, height)?; - } - self.primary.remove(store); - Ok(()) - } - - /// load will return an error if no data is set, or on parse error - pub fn load(&self, store: &dyn Storage) -> StdResult { - self.primary.load(store) - } - - /// may_load will parse the data stored if present, returns Ok(None) if no data there. - /// returns an error on parsing issues - pub fn may_load(&self, store: &dyn Storage) -> StdResult> { - self.primary.may_load(store) - } - - pub fn may_load_at_height(&self, store: &dyn Storage, height: u64) -> StdResult> { - let snapshot = self.snapshots.may_load_at_height(store, (), height)?; - - if let Some(r) = snapshot { - Ok(r) - } else { - // otherwise, return current value - self.may_load(store) - } - } - - // If there is no checkpoint for that height, then we return StdError::NotFound - pub fn assert_checkpointed(&self, store: &dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.assert_checkpointed(store, height) - } - - /// Loads the data, perform the specified action, and store the result in the database. - /// This is a shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - /// - /// This is a bit more customized than needed to only read "old" value 1 time, not 2 per naive approach - pub fn update(&self, store: &mut dyn Storage, height: u64, action: A) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - let input = self.may_load(store)?; - let output = action(input)?; - self.save(store, &output, height)?; - Ok(output) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::bound::Bound; - use cosmwasm_std::testing::MockStorage; - - type TestItem = SnapshotItem<'static, u64>; - - const NEVER: TestItem = - SnapshotItem::new("never", "never__check", "never__change", Strategy::Never); - const EVERY: TestItem = SnapshotItem::new( - "every", - "every__check", - "every__change", - Strategy::EveryBlock, - ); - const SELECT: TestItem = SnapshotItem::new( - "select", - "select__check", - "select__change", - Strategy::Selected, - ); - - // Fills an item (u64) with the following writes: - // 1: 5 - // 2: 7 - // 3: 8 - // 4: 1 - // 5: None - // 6: 13 - // 7: None - // 8: 22 - // Final value: 22 - // Value at beginning of 3 -> 7 - // Value at beginning of 5 -> 1 - fn init_data(item: &TestItem, storage: &mut dyn Storage) { - item.save(storage, &5, 1).unwrap(); - item.save(storage, &7, 2).unwrap(); - - // checkpoint 3 - item.add_checkpoint(storage, 3).unwrap(); - - // also use update to set - to ensure this works - item.save(storage, &1, 3).unwrap(); - item.update(storage, 3, |_| -> StdResult { Ok(8) }) - .unwrap(); - - item.remove(storage, 4).unwrap(); - item.save(storage, &13, 4).unwrap(); - - // checkpoint 5 - item.add_checkpoint(storage, 5).unwrap(); - item.remove(storage, 5).unwrap(); - item.update(storage, 5, |_| -> StdResult { Ok(22) }) - .unwrap(); - // and delete it later (unknown if all data present) - item.remove_checkpoint(storage, 5).unwrap(); - } - - const FINAL_VALUE: Option = Some(22); - - const VALUE_START_3: Option = Some(7); - - const VALUE_START_5: Option = Some(13); - - fn assert_final_value(item: &TestItem, storage: &dyn Storage) { - assert_eq!(FINAL_VALUE, item.may_load(storage).unwrap()); - } - - #[track_caller] - fn assert_value_at_height( - item: &TestItem, - storage: &dyn Storage, - height: u64, - value: Option, - ) { - assert_eq!(value, item.may_load_at_height(storage, height).unwrap()); - } - - fn assert_missing_checkpoint(item: &TestItem, storage: &dyn Storage, height: u64) { - assert!(item.may_load_at_height(storage, height).is_err()); - } - - #[test] - fn never_works_like_normal_item() { - let mut storage = MockStorage::new(); - init_data(&NEVER, &mut storage); - assert_final_value(&NEVER, &storage); - - // historical queries return error - assert_missing_checkpoint(&NEVER, &storage, 3); - assert_missing_checkpoint(&NEVER, &storage, 5); - } - - #[test] - fn every_blocks_stores_present_and_past() { - let mut storage = MockStorage::new(); - init_data(&EVERY, &mut storage); - assert_final_value(&EVERY, &storage); - - // historical queries return historical values - assert_value_at_height(&EVERY, &storage, 3, VALUE_START_3); - assert_value_at_height(&EVERY, &storage, 5, VALUE_START_5); - } - - #[test] - fn selected_shows_3_not_5() { - let mut storage = MockStorage::new(); - init_data(&SELECT, &mut storage); - assert_final_value(&SELECT, &storage); - - // historical queries return historical values - assert_value_at_height(&SELECT, &storage, 3, VALUE_START_3); - // never checkpointed - assert_missing_checkpoint(&NEVER, &storage, 1); - // deleted checkpoint - assert_missing_checkpoint(&NEVER, &storage, 5); - } - - #[test] - fn handle_multiple_writes_in_one_block() { - let mut storage = MockStorage::new(); - - println!("SETUP"); - EVERY.save(&mut storage, &5, 1).unwrap(); - EVERY.save(&mut storage, &7, 2).unwrap(); - EVERY.save(&mut storage, &2, 2).unwrap(); - - // update and save - query at 3 => 2, at 4 => 12 - EVERY - .update(&mut storage, 3, |_| -> StdResult { Ok(9) }) - .unwrap(); - EVERY.save(&mut storage, &12, 3).unwrap(); - assert_eq!(Some(5), EVERY.may_load_at_height(&storage, 2).unwrap()); - assert_eq!(Some(2), EVERY.may_load_at_height(&storage, 3).unwrap()); - assert_eq!(Some(12), EVERY.may_load_at_height(&storage, 4).unwrap()); - - // save and remove - query at 4 => 1, at 5 => None - EVERY.save(&mut storage, &17, 4).unwrap(); - EVERY.remove(&mut storage, 4).unwrap(); - assert_eq!(Some(12), EVERY.may_load_at_height(&storage, 4).unwrap()); - assert_eq!(None, EVERY.may_load_at_height(&storage, 5).unwrap()); - - // remove and update - query at 5 => 2, at 6 => 13 - EVERY.remove(&mut storage, 5).unwrap(); - EVERY - .update(&mut storage, 5, |_| -> StdResult { Ok(2) }) - .unwrap(); - assert_eq!(None, EVERY.may_load_at_height(&storage, 5).unwrap()); - assert_eq!(Some(2), EVERY.may_load_at_height(&storage, 6).unwrap()); - } - - #[test] - #[cfg(feature = "iterator")] - fn changelog_range_works() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - - // simple data for testing - EVERY.save(&mut store, &5, 1u64).unwrap(); - EVERY.save(&mut store, &7, 2u64).unwrap(); - EVERY - .update(&mut store, 3u64, |_| -> StdResult { Ok(8) }) - .unwrap(); - EVERY.remove(&mut store, 4u64).unwrap(); - - // let's try to iterate over the changelog - let all: StdResult> = EVERY - .changelog() - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - (1, ChangeSet { old: None }), - (2, ChangeSet { old: Some(5) }), - (3, ChangeSet { old: Some(7) }), - (4, ChangeSet { old: Some(8) }) - ] - ); - - // let's try to iterate over a changelog range - let all: StdResult> = EVERY - .changelog() - .range(&store, Some(Bound::exclusive(3u64)), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(4, ChangeSet { old: Some(8) }),]); - } -} diff --git a/packages/storage-plus/src/snapshot/map.rs b/packages/storage-plus/src/snapshot/map.rs deleted file mode 100644 index 3d7e6b0e4..000000000 --- a/packages/storage-plus/src/snapshot/map.rs +++ /dev/null @@ -1,644 +0,0 @@ -use serde::de::DeserializeOwned; -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, Prefix}; -use crate::snapshot::{ChangeSet, Snapshot}; -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. -/// What data is snapshotted depends on the Strategy. -pub struct SnapshotMap<'a, K, T> { - primary: Map<'a, K, T>, - snapshots: Snapshot<'a, K, T>, -} - -impl<'a, K, T> SnapshotMap<'a, K, T> { - /// Example: - /// - /// ```rust - /// use cw_storage_plus::{SnapshotMap, Strategy}; - /// - /// SnapshotMap::<&[u8], &str>::new( - /// "never", - /// "never__check", - /// "never__change", - /// Strategy::EveryBlock - /// ); - /// ``` - pub const fn new( - pk: &'a str, - checkpoints: &'a str, - changelog: &'a str, - strategy: Strategy, - ) -> Self { - SnapshotMap { - primary: Map::new(pk), - snapshots: Snapshot::new(checkpoints, changelog, strategy), - } - } - - pub fn changelog(&self) -> &Map<'a, (K, u64), ChangeSet> { - &self.snapshots.changelog - } -} - -impl<'a, K, T> SnapshotMap<'a, K, T> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + Prefixer<'a>, -{ - pub fn add_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.add_checkpoint(store, height) - } - - pub fn remove_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.remove_checkpoint(store, height) - } -} - -impl<'a, K, T> SnapshotMap<'a, K, T> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, -{ - pub fn key(&self, k: K) -> Path { - self.primary.key(k) - } - - fn no_prefix_raw(&self) -> Prefix, T, K> { - self.primary.no_prefix_raw() - } - - /// load old value and store changelog - fn write_change(&self, store: &mut dyn Storage, k: K, height: u64) -> StdResult<()> { - // if there is already data in the changelog for this key and block, do not write more - if self.snapshots.has_changelog(store, k.clone(), height)? { - return Ok(()); - } - // otherwise, store the previous value - let old = self.primary.may_load(store, k.clone())?; - self.snapshots.write_changelog(store, k, height, old) - } - - pub fn save(&self, store: &mut dyn Storage, k: K, data: &T, height: u64) -> StdResult<()> { - if self.snapshots.should_checkpoint(store, &k)? { - self.write_change(store, k.clone(), height)?; - } - self.primary.save(store, k, data) - } - - pub fn remove(&self, store: &mut dyn Storage, k: K, height: u64) -> StdResult<()> { - if self.snapshots.should_checkpoint(store, &k)? { - self.write_change(store, k.clone(), height)?; - } - self.primary.remove(store, k); - Ok(()) - } - - /// load will return an error if no data is set at the given key, or on parse error - pub fn load(&self, store: &dyn Storage, k: K) -> StdResult { - self.primary.load(store, k) - } - - /// may_load will parse the data stored at the key if present, returns Ok(None) if no data there. - /// returns an error on issues parsing - pub fn may_load(&self, store: &dyn Storage, k: K) -> StdResult> { - self.primary.may_load(store, k) - } - - pub fn may_load_at_height( - &self, - store: &dyn Storage, - k: K, - height: u64, - ) -> StdResult> { - let snapshot = self - .snapshots - .may_load_at_height(store, k.clone(), height)?; - - if let Some(r) = snapshot { - Ok(r) - } else { - // otherwise, return current value - self.may_load(store, k) - } - } - - pub fn assert_checkpointed(&self, store: &dyn Storage, height: u64) -> StdResult<()> { - self.snapshots.assert_checkpointed(store, height) - } - - /// Loads the data, perform the specified action, and store the result - /// in the database. This is shorthand for some common sequences, which may be useful. - /// - /// If the data exists, `action(Some(value))` is called. Otherwise `action(None)` is called. - /// - /// This is a bit more customized than needed to only read "old" value 1 time, not 2 per naive approach - pub fn update( - &self, - store: &mut dyn Storage, - k: K, - height: u64, - action: A, - ) -> Result - where - A: FnOnce(Option) -> Result, - E: From, - { - let input = self.may_load(store, k.clone())?; - let output = action(input)?; - self.save(store, k, &output, height)?; - Ok(output) - } -} - -// short-cut for simple keys, rather than .prefix(()).range_raw(...) -impl<'a, K, T> SnapshotMap<'a, K, T> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + Prefixer<'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>( - &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")] -impl<'a, K, T> SnapshotMap<'a, K, T> -where - T: Serialize + DeserializeOwned, - K: PrimaryKey<'a> + KeyDeserialize, -{ - /// While `range` over a `prefix` fixes the prefix to one element and iterates over the - /// remaining, `prefix_range` accepts bounds for the lowest and highest elements of the - /// `Prefix` itself, and iterates over those (inclusively or exclusively, depending on - /// `PrefixBound`). - /// There are some issues that distinguish these two, and blindly casting to `Vec` doesn't - /// solve them. - pub fn prefix_range<'c>( - &self, - store: &'c dyn Storage, - min: Option>, - max: Option>, - order: cosmwasm_std::Order, - ) -> Box> + 'c> - where - T: 'c, - 'a: 'c, - K: 'c, - K::Output: 'static, - { - let mapped = namespaced_prefix_range(store, self.primary.namespace(), min, max, order) - .map(deserialize_kv::); - Box::new(mapped) - } - - pub fn range<'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().range(store, min, max, order) - } - - pub fn keys<'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().keys(store, min, max, order) - } - - pub fn prefix(&self, p: K::Prefix) -> Prefix { - Prefix::new(self.primary.namespace(), &p.prefix()) - } - - pub fn sub_prefix(&self, p: K::SubPrefix) -> Prefix { - Prefix::new(self.primary.namespace(), &p.prefix()) - } - - fn no_prefix(&self) -> Prefix { - Prefix::new(self.primary.namespace(), &[]) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - type TestMap = SnapshotMap<'static, &'static str, u64>; - type TestMapCompositeKey = SnapshotMap<'static, (&'static str, &'static str), u64>; - - const NEVER: TestMap = - SnapshotMap::new("never", "never__check", "never__change", Strategy::Never); - const EVERY: TestMap = SnapshotMap::new( - "every", - "every__check", - "every__change", - Strategy::EveryBlock, - ); - const EVERY_COMPOSITE_KEY: TestMapCompositeKey = SnapshotMap::new( - "every", - "every__check", - "every__change", - Strategy::EveryBlock, - ); - const SELECT: TestMap = SnapshotMap::new( - "select", - "select__check", - "select__change", - Strategy::Selected, - ); - - // Fills a map &[u8] -> u64 with the following writes: - // 1: A = 5 - // 2: B = 7 - // 3: C = 1, A = 8 - // 4: B = None, C = 13 - // 5: A = None, D = 22 - // Final values -> C = 13, D = 22 - // Values at beginning of 3 -> A = 5, B = 7 - // Values at beginning of 5 -> A = 8, C = 13 - fn init_data(map: &TestMap, storage: &mut dyn Storage) { - map.save(storage, "A", &5, 1).unwrap(); - map.save(storage, "B", &7, 2).unwrap(); - - // checkpoint 3 - map.add_checkpoint(storage, 3).unwrap(); - - // also use update to set - to ensure this works - map.save(storage, "C", &1, 3).unwrap(); - map.update(storage, "A", 3, |_| -> StdResult { Ok(8) }) - .unwrap(); - - map.remove(storage, "B", 4).unwrap(); - map.save(storage, "C", &13, 4).unwrap(); - - // checkpoint 5 - map.add_checkpoint(storage, 5).unwrap(); - map.remove(storage, "A", 5).unwrap(); - map.update(storage, "D", 5, |_| -> StdResult { Ok(22) }) - .unwrap(); - // and delete it later (unknown if all data present) - map.remove_checkpoint(storage, 5).unwrap(); - } - - const FINAL_VALUES: &[(&str, Option)] = - &[("A", None), ("B", None), ("C", Some(13)), ("D", Some(22))]; - - const VALUES_START_3: &[(&str, Option)] = - &[("A", Some(5)), ("B", Some(7)), ("C", None), ("D", None)]; - - const VALUES_START_5: &[(&str, Option)] = - &[("A", Some(8)), ("B", None), ("C", Some(13)), ("D", None)]; - - // Same as `init_data`, but we have a composite key for testing range. - fn init_data_composite_key(map: &TestMapCompositeKey, storage: &mut dyn Storage) { - map.save(storage, ("A", "B"), &5, 1).unwrap(); - map.save(storage, ("B", "A"), &7, 2).unwrap(); - - // checkpoint 3 - map.add_checkpoint(storage, 3).unwrap(); - - // also use update to set - to ensure this works - map.save(storage, ("B", "B"), &1, 3).unwrap(); - map.update(storage, ("A", "B"), 3, |_| -> StdResult { Ok(8) }) - .unwrap(); - - map.remove(storage, ("B", "A"), 4).unwrap(); - map.save(storage, ("B", "B"), &13, 4).unwrap(); - - // checkpoint 5 - map.add_checkpoint(storage, 5).unwrap(); - map.remove(storage, ("A", "B"), 5).unwrap(); - map.update(storage, ("C", "A"), 5, |_| -> StdResult { Ok(22) }) - .unwrap(); - // and delete it later (unknown if all data present) - map.remove_checkpoint(storage, 5).unwrap(); - } - - fn assert_final_values(map: &TestMap, storage: &dyn Storage) { - for (k, v) in FINAL_VALUES.iter().cloned() { - assert_eq!(v, map.may_load(storage, k).unwrap()); - } - } - - fn assert_values_at_height( - map: &TestMap, - storage: &dyn Storage, - height: u64, - values: &[(&str, Option)], - ) { - for (k, v) in values.iter().cloned() { - assert_eq!(v, map.may_load_at_height(storage, k, height).unwrap()); - } - } - - fn assert_missing_checkpoint(map: &TestMap, storage: &dyn Storage, height: u64) { - for k in &["A", "B", "C", "D"] { - assert!(map.may_load_at_height(storage, *k, height).is_err()); - } - } - - #[test] - fn never_works_like_normal_map() { - let mut storage = MockStorage::new(); - init_data(&NEVER, &mut storage); - assert_final_values(&NEVER, &storage); - - // historical queries return error - assert_missing_checkpoint(&NEVER, &storage, 3); - assert_missing_checkpoint(&NEVER, &storage, 5); - } - - #[test] - fn every_blocks_stores_present_and_past() { - let mut storage = MockStorage::new(); - init_data(&EVERY, &mut storage); - assert_final_values(&EVERY, &storage); - - // historical queries return historical values - assert_values_at_height(&EVERY, &storage, 3, VALUES_START_3); - assert_values_at_height(&EVERY, &storage, 5, VALUES_START_5); - } - - #[test] - fn selected_shows_3_not_5() { - let mut storage = MockStorage::new(); - init_data(&SELECT, &mut storage); - assert_final_values(&SELECT, &storage); - - // historical queries return historical values - assert_values_at_height(&SELECT, &storage, 3, VALUES_START_3); - // never checkpointed - assert_missing_checkpoint(&NEVER, &storage, 1); - // deleted checkpoint - assert_missing_checkpoint(&NEVER, &storage, 5); - } - - #[test] - fn handle_multiple_writes_in_one_block() { - let mut storage = MockStorage::new(); - - println!("SETUP"); - EVERY.save(&mut storage, "A", &5, 1).unwrap(); - EVERY.save(&mut storage, "B", &7, 2).unwrap(); - EVERY.save(&mut storage, "C", &2, 2).unwrap(); - - // update and save - A query at 3 => 5, at 4 => 12 - EVERY - .update(&mut storage, "A", 3, |_| -> StdResult { Ok(9) }) - .unwrap(); - EVERY.save(&mut storage, "A", &12, 3).unwrap(); - assert_eq!(Some(5), EVERY.may_load_at_height(&storage, "A", 2).unwrap()); - assert_eq!(Some(5), EVERY.may_load_at_height(&storage, "A", 3).unwrap()); - assert_eq!( - Some(12), - EVERY.may_load_at_height(&storage, "A", 4).unwrap() - ); - - // save and remove - B query at 4 => 7, at 5 => None - EVERY.save(&mut storage, "B", &17, 4).unwrap(); - EVERY.remove(&mut storage, "B", 4).unwrap(); - assert_eq!(Some(7), EVERY.may_load_at_height(&storage, "B", 3).unwrap()); - assert_eq!(Some(7), EVERY.may_load_at_height(&storage, "B", 4).unwrap()); - assert_eq!(None, EVERY.may_load_at_height(&storage, "B", 5).unwrap()); - - // remove and update - C query at 5 => 2, at 6 => 16 - EVERY.remove(&mut storage, "C", 5).unwrap(); - EVERY - .update(&mut storage, "C", 5, |_| -> StdResult { Ok(16) }) - .unwrap(); - assert_eq!(Some(2), EVERY.may_load_at_height(&storage, "C", 4).unwrap()); - assert_eq!(Some(2), EVERY.may_load_at_height(&storage, "C", 5).unwrap()); - assert_eq!( - Some(16), - EVERY.may_load_at_height(&storage, "C", 6).unwrap() - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn changelog_range_works() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - - // simple data for testing - EVERY.save(&mut store, "A", &5, 1).unwrap(); - EVERY.save(&mut store, "B", &7, 2).unwrap(); - EVERY - .update(&mut store, "A", 3, |_| -> StdResult { Ok(8) }) - .unwrap(); - EVERY.remove(&mut store, "B", 4).unwrap(); - - // let's try to iterate over the changelog - let all: StdResult> = EVERY - .changelog() - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(4, all.len()); - assert_eq!( - all, - vec![ - (("A".into(), 1), ChangeSet { old: None }), - (("A".into(), 3), ChangeSet { old: Some(5) }), - (("B".into(), 2), ChangeSet { old: None }), - (("B".into(), 4), ChangeSet { old: Some(7) }) - ] - ); - - // let's try to iterate over a changelog key/prefix - let all: StdResult> = EVERY - .changelog() - .prefix("B") - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - (2, ChangeSet { old: None }), - (4, ChangeSet { old: Some(7) }) - ] - ); - - // let's try to iterate over a changelog prefixed range - let all: StdResult> = EVERY - .changelog() - .prefix("A") - .range(&store, Some(Bound::inclusive(3u64)), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(3, ChangeSet { old: Some(5) }),]); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_simple_string_key() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - init_data(&EVERY, &mut store); - - // let's try to iterate! - let all: StdResult> = EVERY.range(&store, None, None, Order::Ascending).collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!(all, vec![("C".into(), 13), ("D".into(), 22)]); - - // let's try to iterate over a range - let all: StdResult> = EVERY - .range(&store, Some(Bound::inclusive("C")), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!(all, vec![("C".into(), 13), ("D".into(), 22)]); - - // let's try to iterate over a more restrictive range - let all: StdResult> = EVERY - .range(&store, Some(Bound::inclusive("D")), None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![("D".into(), 22)]); - } - - #[test] - #[cfg(feature = "iterator")] - fn range_composite_key() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - init_data_composite_key(&EVERY_COMPOSITE_KEY, &mut store); - - // let's try to iterate! - let all: StdResult> = EVERY_COMPOSITE_KEY - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - (("B".into(), "B".into()), 13), - (("C".into(), "A".into()), 22) - ] - ); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_range_composite_key() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - init_data_composite_key(&EVERY_COMPOSITE_KEY, &mut store); - - // let's prefix-range and iterate - let all: StdResult> = EVERY_COMPOSITE_KEY - .prefix_range( - &store, - None, - Some(PrefixBound::exclusive("C")), - Order::Descending, - ) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![(("B".into(), "B".into()), 13)]); - } - - #[test] - #[cfg(feature = "iterator")] - fn prefix_composite_key() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - init_data_composite_key(&EVERY_COMPOSITE_KEY, &mut store); - - // let's prefix and iterate - let all: StdResult> = EVERY_COMPOSITE_KEY - .prefix("C") - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(1, all.len()); - assert_eq!(all, vec![("A".into(), 22),]); - } - - #[test] - #[cfg(feature = "iterator")] - fn sub_prefix_composite_key() { - use cosmwasm_std::Order; - - let mut store = MockStorage::new(); - init_data_composite_key(&EVERY_COMPOSITE_KEY, &mut store); - - // Let's sub-prefix and iterate. - // This is similar to calling range() directly, but added here for completeness / - // sub_prefix type checks - let all: StdResult> = EVERY_COMPOSITE_KEY - .sub_prefix(()) - .range(&store, None, None, Order::Ascending) - .collect(); - let all = all.unwrap(); - assert_eq!(2, all.len()); - assert_eq!( - all, - vec![ - (("B".into(), "B".into()), 13), - (("C".into(), "A".into()), 22) - ] - ); - } -} diff --git a/packages/storage-plus/src/snapshot/mod.rs b/packages/storage-plus/src/snapshot/mod.rs deleted file mode 100644 index 7fccfea7d..000000000 --- a/packages/storage-plus/src/snapshot/mod.rs +++ /dev/null @@ -1,392 +0,0 @@ -#![cfg(feature = "iterator")] -mod item; -mod map; - -pub use item::SnapshotItem; -pub use map::SnapshotMap; - -use crate::bound::Bound; -use crate::de::KeyDeserialize; -use crate::{Map, Prefixer, PrimaryKey}; -use cosmwasm_std::{Order, StdError, StdResult, Storage}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; - -/// Structure holding a map of checkpoints composited from -/// height (as u64) and counter of how many times it has -/// been checkpointed (as u32). -/// Stores all changes in changelog. -#[derive(Debug, Clone)] -pub(crate) struct Snapshot<'a, K, T> { - checkpoints: Map<'a, u64, u32>, - - // this stores all changes (key, height). Must differentiate between no data written, - // and explicit None (just inserted) - pub changelog: Map<'a, (K, u64), ChangeSet>, - - // How aggressive we are about checkpointing all data - strategy: Strategy, -} - -impl<'a, K, T> Snapshot<'a, K, T> { - pub const fn new( - checkpoints: &'a str, - changelog: &'a str, - strategy: Strategy, - ) -> Snapshot<'a, K, T> { - Snapshot { - checkpoints: Map::new(checkpoints), - changelog: Map::new(changelog), - strategy, - } - } - - pub fn add_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - self.checkpoints - .update::<_, StdError>(store, height, |count| Ok(count.unwrap_or_default() + 1))?; - Ok(()) - } - - pub fn remove_checkpoint(&self, store: &mut dyn Storage, height: u64) -> StdResult<()> { - let count = self - .checkpoints - .may_load(store, height)? - .unwrap_or_default(); - if count <= 1 { - self.checkpoints.remove(store, height); - Ok(()) - } else { - self.checkpoints.save(store, height, &(count - 1)) - } - } -} - -impl<'a, K, T> Snapshot<'a, K, T> -where - T: Serialize + DeserializeOwned + Clone, - K: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, -{ - /// should_checkpoint looks at the strategy and determines if we want to checkpoint - pub fn should_checkpoint(&self, store: &dyn Storage, k: &K) -> StdResult { - match self.strategy { - Strategy::EveryBlock => Ok(true), - Strategy::Never => Ok(false), - Strategy::Selected => self.should_checkpoint_selected(store, k), - } - } - - /// this is just pulled out from above for the selected block - fn should_checkpoint_selected(&self, store: &dyn Storage, k: &K) -> StdResult { - // most recent checkpoint - let checkpoint = self - .checkpoints - .range(store, None, None, Order::Descending) - .next() - .transpose()?; - if let Some((height, _)) = checkpoint { - // any changelog for the given key since then? - let start = Bound::inclusive(height); - let first = self - .changelog - .prefix(k.clone()) - .range_raw(store, Some(start), None, Order::Ascending) - .next() - .transpose()?; - if first.is_none() { - // there must be at least one open checkpoint and no changelog for the given height since then - return Ok(true); - } - } - // otherwise, we don't save this - Ok(false) - } - - // If there is no checkpoint for that height, then we return StdError::NotFound - pub fn assert_checkpointed(&self, store: &dyn Storage, height: u64) -> StdResult<()> { - let has = match self.strategy { - Strategy::EveryBlock => true, - Strategy::Never => false, - Strategy::Selected => self.checkpoints.may_load(store, height)?.is_some(), - }; - match has { - true => Ok(()), - false => Err(StdError::not_found("checkpoint")), - } - } - - pub fn has_changelog(&self, store: &mut dyn Storage, key: K, height: u64) -> StdResult { - Ok(self.changelog.may_load(store, (key, height))?.is_some()) - } - - pub fn write_changelog( - &self, - store: &mut dyn Storage, - key: K, - height: u64, - old: Option, - ) -> StdResult<()> { - self.changelog - .save(store, (key, height), &ChangeSet { old }) - } - - // may_load_at_height reads historical data from given checkpoints. - // Returns StdError::NotFound if we have no checkpoint, and can give no data. - // Returns Ok(None) if there is a checkpoint, but no cached data (no changes since the - // checkpoint. Caller should query current state). - // Return Ok(Some(x)) if there is a checkpoint and data written to changelog, returning the state at that time - pub fn may_load_at_height( - &self, - store: &dyn Storage, - key: K, - height: u64, - ) -> StdResult>> { - self.assert_checkpointed(store, height)?; - - // this will look for the first snapshot of height >= given height - // If None, there is no snapshot since that time. - let start = Bound::inclusive(height); - let first = self - .changelog - .prefix(key) - .range_raw(store, Some(start), None, Order::Ascending) - .next(); - - if let Some(r) = first { - // if we found a match, return this last one - r.map(|(_, v)| Some(v.old)) - } else { - Ok(None) - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)] -pub enum Strategy { - EveryBlock, - Never, - /// Only writes for linked blocks - does a few more reads to save some writes. - /// Probably uses more gas, but less total disk usage. - /// - /// Note that you need a trusted source (eg. own contract) to set/remove checkpoints. - /// Useful when the checkpoint setting happens in the same contract as the snapshotting. - Selected, -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)] -pub struct ChangeSet { - pub old: Option, -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - type TestSnapshot = Snapshot<'static, &'static str, u64>; - - const NEVER: TestSnapshot = Snapshot::new("never__check", "never__change", Strategy::Never); - const EVERY: TestSnapshot = - Snapshot::new("every__check", "every__change", Strategy::EveryBlock); - const SELECT: TestSnapshot = - Snapshot::new("select__check", "select__change", Strategy::Selected); - - const DUMMY_KEY: &str = "dummy"; - - #[test] - fn should_checkpoint() { - let storage = MockStorage::new(); - - assert_eq!(NEVER.should_checkpoint(&storage, &DUMMY_KEY), Ok(false)); - assert_eq!(EVERY.should_checkpoint(&storage, &DUMMY_KEY), Ok(true)); - assert_eq!(SELECT.should_checkpoint(&storage, &DUMMY_KEY), Ok(false)); - } - - #[test] - fn assert_checkpointed() { - let mut storage = MockStorage::new(); - - assert_eq!( - NEVER.assert_checkpointed(&storage, 1), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!(EVERY.assert_checkpointed(&storage, 1), Ok(())); - assert_eq!( - SELECT.assert_checkpointed(&storage, 1), - Err(StdError::not_found("checkpoint")) - ); - - // Add a checkpoint at 1 - NEVER.add_checkpoint(&mut storage, 1).unwrap(); - EVERY.add_checkpoint(&mut storage, 1).unwrap(); - SELECT.add_checkpoint(&mut storage, 1).unwrap(); - - assert_eq!( - NEVER.assert_checkpointed(&storage, 1), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!(EVERY.assert_checkpointed(&storage, 1), Ok(())); - assert_eq!(SELECT.assert_checkpointed(&storage, 1), Ok(())); - - // Remove checkpoint - NEVER.remove_checkpoint(&mut storage, 1).unwrap(); - EVERY.remove_checkpoint(&mut storage, 1).unwrap(); - SELECT.remove_checkpoint(&mut storage, 1).unwrap(); - - assert_eq!( - NEVER.assert_checkpointed(&storage, 1), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!(EVERY.assert_checkpointed(&storage, 1), Ok(())); - assert_eq!( - SELECT.assert_checkpointed(&storage, 1), - Err(StdError::not_found("checkpoint")) - ); - } - - #[test] - fn has_changelog() { - let mut storage = MockStorage::new(); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(false)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(false)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(false)); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - - // Write a changelog at 2 - NEVER - .write_changelog(&mut storage, DUMMY_KEY, 2, Some(3)) - .unwrap(); - EVERY - .write_changelog(&mut storage, DUMMY_KEY, 2, Some(4)) - .unwrap(); - SELECT - .write_changelog(&mut storage, DUMMY_KEY, 2, Some(5)) - .unwrap(); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 1), Ok(false)); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(true)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(true)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 2), Ok(true)); - - assert_eq!(NEVER.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - assert_eq!(EVERY.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - assert_eq!(SELECT.has_changelog(&mut storage, DUMMY_KEY, 3), Ok(false)); - } - - #[test] - fn may_load_at_height() { - let mut storage = MockStorage::new(); - - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 3), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!(EVERY.may_load_at_height(&storage, DUMMY_KEY, 3), Ok(None)); - assert_eq!( - SELECT.may_load_at_height(&storage, DUMMY_KEY, 3), - Err(StdError::not_found("checkpoint")) - ); - - // Add a checkpoint at 3 - NEVER.add_checkpoint(&mut storage, 3).unwrap(); - EVERY.add_checkpoint(&mut storage, 3).unwrap(); - SELECT.add_checkpoint(&mut storage, 3).unwrap(); - - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 3), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!(EVERY.may_load_at_height(&storage, DUMMY_KEY, 3), Ok(None)); - assert_eq!(SELECT.may_load_at_height(&storage, DUMMY_KEY, 3), Ok(None)); - - // Write a changelog at 3 - NEVER - .write_changelog(&mut storage, DUMMY_KEY, 3, Some(100)) - .unwrap(); - EVERY - .write_changelog(&mut storage, DUMMY_KEY, 3, Some(101)) - .unwrap(); - SELECT - .write_changelog(&mut storage, DUMMY_KEY, 3, Some(102)) - .unwrap(); - - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 3), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!( - EVERY.may_load_at_height(&storage, DUMMY_KEY, 3), - Ok(Some(Some(101))) - ); - assert_eq!( - SELECT.may_load_at_height(&storage, DUMMY_KEY, 3), - Ok(Some(Some(102))) - ); - // Check that may_load_at_height at a previous value will return the first change after that. - // (Only with EVERY). - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 2), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!( - EVERY.may_load_at_height(&storage, DUMMY_KEY, 2), - Ok(Some(Some(101))) - ); - assert_eq!( - SELECT.may_load_at_height(&storage, DUMMY_KEY, 2), - Err(StdError::not_found("checkpoint")) - ); - - // Write a changelog at 4, removing the value - NEVER - .write_changelog(&mut storage, DUMMY_KEY, 4, None) - .unwrap(); - EVERY - .write_changelog(&mut storage, DUMMY_KEY, 4, None) - .unwrap(); - SELECT - .write_changelog(&mut storage, DUMMY_KEY, 4, None) - .unwrap(); - // And add a checkpoint at 4 - NEVER.add_checkpoint(&mut storage, 4).unwrap(); - EVERY.add_checkpoint(&mut storage, 4).unwrap(); - SELECT.add_checkpoint(&mut storage, 4).unwrap(); - - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 4), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!( - EVERY.may_load_at_height(&storage, DUMMY_KEY, 4), - Ok(Some(None)) - ); - assert_eq!( - SELECT.may_load_at_height(&storage, DUMMY_KEY, 4), - Ok(Some(None)) - ); - - // Confirm old value at 3 - assert_eq!( - NEVER.may_load_at_height(&storage, DUMMY_KEY, 3), - Err(StdError::not_found("checkpoint")) - ); - assert_eq!( - EVERY.may_load_at_height(&storage, DUMMY_KEY, 3), - Ok(Some(Some(101))) - ); - assert_eq!( - SELECT.may_load_at_height(&storage, DUMMY_KEY, 3), - Ok(Some(Some(102))) - ); - } -} diff --git a/packages/storage-plus/tests/index_list.rs b/packages/storage-plus/tests/index_list.rs deleted file mode 100644 index db0d2b843..000000000 --- a/packages/storage-plus/tests/index_list.rs +++ /dev/null @@ -1,76 +0,0 @@ -#[cfg(all(test, feature = "iterator", feature = "macro"))] -mod test { - use cosmwasm_std::{testing::MockStorage, Addr}; - use cw_storage_macro::index_list; - use cw_storage_plus::{IndexedMap, MultiIndex, UniqueIndex}; - use serde::{Deserialize, Serialize}; - - #[test] - fn index_list_compiles() { - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] - struct TestStruct { - id: u64, - id2: u32, - addr: Addr, - } - - #[index_list(TestStruct)] - struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, - } - - let _: IndexedMap = IndexedMap::new( - "t", - TestIndexes { - id: MultiIndex::new(|_pk, t| t.id2, "t", "t_id2"), - addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), - }, - ); - } - - #[test] - fn index_list_works() { - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] - struct TestStruct { - id: u64, - id2: u32, - addr: Addr, - } - - #[index_list(TestStruct)] - struct TestIndexes<'a> { - id: MultiIndex<'a, u32, TestStruct, u64>, - addr: UniqueIndex<'a, Addr, TestStruct>, - } - - let mut storage = MockStorage::new(); - let idm: IndexedMap = IndexedMap::new( - "t", - TestIndexes { - id: MultiIndex::new(|_pk, t| t.id2, "t", "t_2"), - addr: UniqueIndex::new(|t| t.addr.clone(), "t_addr"), - }, - ); - - idm.save( - &mut storage, - 0, - &TestStruct { - id: 0, - id2: 100, - addr: Addr::unchecked("1"), - }, - ) - .unwrap(); - - assert_eq!( - idm.load(&storage, 0).unwrap(), - TestStruct { - id: 0, - id2: 100, - addr: Addr::unchecked("1"), - } - ); - } -} diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml deleted file mode 100644 index 3611a9c26..000000000 --- a/packages/utils/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "cw-utils" -version = "0.16.0" -authors = ["Ethan Frey "] -edition = "2018" -description = "Common helpers for other cw specs" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -schemars = "0.8.1" -semver = "1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = "1.0.21" - -[dev-dependencies] -cw-storage-plus = { path = "../../packages/storage-plus", version = "0.16.0" } -prost = "0.9" diff --git a/packages/utils/NOTICE b/packages/utils/NOTICE deleted file mode 100644 index 6ce7d69d2..000000000 --- a/packages/utils/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Utils: Common types and helpers for CosmWasm specs -Copyright (C) 2020 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/utils/README.md b/packages/utils/README.md deleted file mode 100644 index cfff5a1f5..000000000 --- a/packages/utils/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Utils: Common types / utilities for specs - -This is a collection of common types shared among many specs. -For example `Expiration`, which is embedded in many places. - -Types should only be added here after they are duplicated in -a second contract, not "because we might need it" diff --git a/packages/utils/src/balance.rs b/packages/utils/src/balance.rs deleted file mode 100644 index 16a15d561..000000000 --- a/packages/utils/src/balance.rs +++ /dev/null @@ -1,319 +0,0 @@ -use std::{fmt, ops}; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Coin, OverflowError, OverflowOperation, StdError, StdResult, Uint128}; - -// Balance wraps Vec and provides some nice helpers. It mutates the Vec and can be -// unwrapped when done. -#[cw_serde] -#[derive(Default)] -pub struct NativeBalance(pub Vec); - -impl NativeBalance { - pub fn into_vec(self) -> Vec { - self.0 - } - - /// returns true if the list of coins has at least the required amount - pub fn has(&self, required: &Coin) -> bool { - self.0 - .iter() - .find(|c| c.denom == required.denom) - .map(|m| m.amount >= required.amount) - .unwrap_or(false) - } - - /// normalize Wallet (sorted by denom, no 0 elements, no duplicate denoms) - pub fn normalize(&mut self) { - // drop 0's - self.0.retain(|c| c.amount.u128() != 0); - // sort - self.0.sort_unstable_by(|a, b| a.denom.cmp(&b.denom)); - - // find all i where (self[i-1].denom == self[i].denom). - let mut dups: Vec = self - .0 - .iter() - .enumerate() - .filter_map(|(i, c)| { - if i != 0 && c.denom == self.0[i - 1].denom { - Some(i) - } else { - None - } - }) - .collect(); - dups.reverse(); - - // we go through the dups in reverse order (to avoid shifting indexes of other ones) - for dup in dups { - let add = self.0[dup].amount; - self.0[dup - 1].amount += add; - self.0.remove(dup); - } - } - - fn find(&self, denom: &str) -> Option<(usize, &Coin)> { - self.0.iter().enumerate().find(|(_i, c)| c.denom == denom) - } - - /// insert_pos should only be called when denom is not in the Wallet. - /// it returns the position where denom should be inserted at (via splice). - /// It returns None if this should be appended - fn insert_pos(&self, denom: &str) -> Option { - self.0.iter().position(|c| c.denom.as_str() >= denom) - } - - pub fn is_empty(&self) -> bool { - !self.0.iter().any(|x| x.amount != Uint128::zero()) - } - - /// similar to `Balance.sub`, but doesn't fail when minuend less than subtrahend - pub fn sub_saturating(mut self, other: Coin) -> StdResult { - match self.find(&other.denom) { - Some((i, c)) => { - if c.amount <= other.amount { - self.0.remove(i); - } else { - self.0[i].amount = self.0[i].amount.checked_sub(other.amount)?; - } - } - // error if no tokens - None => { - return Err(StdError::overflow(OverflowError::new( - OverflowOperation::Sub, - 0, - other.amount.u128(), - ))) - } - }; - Ok(self) - } -} - -impl fmt::Display for NativeBalance { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for c in &self.0 { - write!(f, "{}{}", c.denom, c.amount)? - } - Ok(()) - } -} - -impl ops::AddAssign for NativeBalance { - fn add_assign(&mut self, other: Coin) { - match self.find(&other.denom) { - Some((i, c)) => { - self.0[i].amount = c.amount + other.amount; - } - // place this in proper sorted order - None => match self.insert_pos(&other.denom) { - Some(idx) => self.0.insert(idx, other), - None => self.0.push(other), - }, - }; - } -} - -impl ops::Add for NativeBalance { - type Output = Self; - - fn add(mut self, other: Coin) -> Self { - self += other; - self - } -} - -impl ops::AddAssign for NativeBalance { - fn add_assign(&mut self, other: NativeBalance) { - for coin in other.0.into_iter() { - self.add_assign(coin); - } - } -} - -impl ops::Add for NativeBalance { - type Output = Self; - - fn add(mut self, other: NativeBalance) -> Self { - self += other; - self - } -} - -impl ops::Sub for NativeBalance { - type Output = StdResult; - - fn sub(mut self, other: Coin) -> StdResult { - match self.find(&other.denom) { - Some((i, c)) => { - let remainder = c.amount.checked_sub(other.amount)?; - if remainder.u128() == 0 { - self.0.remove(i); - } else { - self.0[i].amount = remainder; - } - } - // error if no tokens - None => { - return Err(StdError::overflow(OverflowError::new( - OverflowOperation::Sub, - 0, - other.amount.u128(), - ))) - } - }; - Ok(self) - } -} - -impl ops::Sub> for NativeBalance { - type Output = StdResult; - - fn sub(self, amount: Vec) -> StdResult { - let mut res = self; - for coin in amount { - res = res.sub(coin.clone())?; - } - Ok(res) - } -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::coin; - - #[test] - fn balance_has_works() { - let balance = NativeBalance(vec![coin(555, "BTC"), coin(12345, "ETH")]); - - // less than same type - assert!(balance.has(&coin(777, "ETH"))); - // equal to same type - assert!(balance.has(&coin(555, "BTC"))); - - // too high - assert!(!balance.has(&coin(12346, "ETH"))); - // wrong type - assert!(!balance.has(&coin(456, "ETC"))); - } - - #[test] - fn balance_add_works() { - let balance = NativeBalance(vec![coin(555, "BTC"), coin(12345, "ETH")]); - - // add an existing coin - let more_eth = balance.clone() + coin(54321, "ETH"); - assert_eq!( - more_eth, - NativeBalance(vec![coin(555, "BTC"), coin(66666, "ETH")]) - ); - - // add an new coin - let add_atom = balance + coin(777, "ATOM"); - assert_eq!( - add_atom, - NativeBalance(vec![ - coin(777, "ATOM"), - coin(555, "BTC"), - coin(12345, "ETH"), - ]) - ); - } - - #[test] - fn balance_in_place_addition() { - let mut balance = NativeBalance(vec![coin(555, "BTC")]); - balance += coin(777, "ATOM"); - assert_eq!( - &balance, - &NativeBalance(vec![coin(777, "ATOM"), coin(555, "BTC")]) - ); - - balance += NativeBalance(vec![coin(666, "ETH"), coin(123, "ATOM")]); - assert_eq!( - &balance, - &NativeBalance(vec![coin(900, "ATOM"), coin(555, "BTC"), coin(666, "ETH")]) - ); - - let sum = balance + NativeBalance(vec![coin(234, "BTC")]); - assert_eq!( - sum, - NativeBalance(vec![coin(900, "ATOM"), coin(789, "BTC"), coin(666, "ETH")]) - ); - } - - #[test] - fn balance_subtract_works() { - let balance = NativeBalance(vec![coin(555, "BTC"), coin(12345, "ETH")]); - - // subtract less than we have - let less_eth = (balance.clone() - coin(2345, "ETH")).unwrap(); - assert_eq!( - less_eth, - NativeBalance(vec![coin(555, "BTC"), coin(10000, "ETH")]) - ); - - // subtract all of one coin (and remove with 0 amount) - let no_btc = (balance.clone() - coin(555, "BTC")).unwrap(); - assert_eq!(no_btc, NativeBalance(vec![coin(12345, "ETH")])); - - // subtract more than we have - let underflow = balance.clone() - coin(666, "BTC"); - assert!(underflow.is_err()); - - // subtract non-existent denom - let missing = balance - coin(1, "ATOM"); - assert!(missing.is_err()); - } - - #[test] - fn balance_subtract_saturating_works() { - let balance = NativeBalance(vec![coin(555, "BTC"), coin(12345, "ETH")]); - - // subtract less than we have - let less_eth = balance.clone().sub_saturating(coin(2345, "ETH")).unwrap(); - assert_eq!( - less_eth, - NativeBalance(vec![coin(555, "BTC"), coin(10000, "ETH")]) - ); - - // subtract all of one coin (and remove with 0 amount) - let no_btc = balance.clone().sub_saturating(coin(555, "BTC")).unwrap(); - assert_eq!(no_btc, NativeBalance(vec![coin(12345, "ETH")])); - - // subtract more than we have - let saturating = balance.clone().sub_saturating(coin(666, "BTC")); - assert!(saturating.is_ok()); - assert_eq!(saturating.unwrap(), NativeBalance(vec![coin(12345, "ETH")])); - - // subtract non-existent denom - let missing = balance - coin(1, "ATOM"); - assert!(missing.is_err()); - } - - #[test] - fn normalize_balance() { - // remove 0 value items and sort - let mut balance = NativeBalance(vec![coin(123, "ETH"), coin(0, "BTC"), coin(8990, "ATOM")]); - balance.normalize(); - assert_eq!( - balance, - NativeBalance(vec![coin(8990, "ATOM"), coin(123, "ETH")]) - ); - - // merge duplicate entries of same denom - let mut balance = NativeBalance(vec![ - coin(123, "ETH"), - coin(789, "BTC"), - coin(321, "ETH"), - coin(11, "BTC"), - ]); - balance.normalize(); - assert_eq!( - balance, - NativeBalance(vec![coin(800, "BTC"), coin(444, "ETH")]) - ); - } -} diff --git a/packages/utils/src/event.rs b/packages/utils/src/event.rs deleted file mode 100644 index 79abed5a5..000000000 --- a/packages/utils/src/event.rs +++ /dev/null @@ -1,7 +0,0 @@ -use cosmwasm_std::Response; - -/// This defines a set of attributes which should be added to `Response`. -pub trait Event { - /// Append attributes to response - fn add_attributes(&self, response: &mut Response); -} diff --git a/packages/utils/src/expiration.rs b/packages/utils/src/expiration.rs deleted file mode 100644 index fe1d707dc..000000000 --- a/packages/utils/src/expiration.rs +++ /dev/null @@ -1,237 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{BlockInfo, StdError, StdResult, Timestamp}; -use std::cmp::Ordering; -use std::fmt; -use std::ops::{Add, Mul}; - -/// Expiration represents a point in time when some event happens. -/// It can compare with a BlockInfo and will return is_expired() == true -/// once the condition is hit (and for every block in the future) -#[cw_serde] -#[derive(Copy)] -pub enum Expiration { - /// AtHeight will expire when `env.block.height` >= height - AtHeight(u64), - /// AtTime will expire when `env.block.time` >= time - AtTime(Timestamp), - /// Never will never expire. Used to express the empty variant - Never {}, -} - -impl fmt::Display for Expiration { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Expiration::AtHeight(height) => write!(f, "expiration height: {}", height), - Expiration::AtTime(time) => write!(f, "expiration time: {}", time), - Expiration::Never {} => write!(f, "expiration: never"), - } - } -} - -/// The default (empty value) is to never expire -impl Default for Expiration { - fn default() -> Self { - Expiration::Never {} - } -} - -impl Expiration { - pub fn is_expired(&self, block: &BlockInfo) -> bool { - match self { - Expiration::AtHeight(height) => block.height >= *height, - Expiration::AtTime(time) => block.time >= *time, - Expiration::Never {} => false, - } - } -} - -impl Add for Expiration { - type Output = StdResult; - - fn add(self, duration: Duration) -> StdResult { - match (self, duration) { - (Expiration::AtTime(t), Duration::Time(delta)) => { - Ok(Expiration::AtTime(t.plus_seconds(delta))) - } - (Expiration::AtHeight(h), Duration::Height(delta)) => { - Ok(Expiration::AtHeight(h + delta)) - } - (Expiration::Never {}, _) => Ok(Expiration::Never {}), - _ => Err(StdError::generic_err("Cannot add height and time")), - } - } -} - -// TODO: does this make sense? do we get expected info/error when None is returned??? -impl PartialOrd for Expiration { - fn partial_cmp(&self, other: &Expiration) -> Option { - match (self, other) { - // compare if both height or both time - (Expiration::AtHeight(h1), Expiration::AtHeight(h2)) => Some(h1.cmp(h2)), - (Expiration::AtTime(t1), Expiration::AtTime(t2)) => Some(t1.cmp(t2)), - // if at least one is never, we can compare with anything - (Expiration::Never {}, Expiration::Never {}) => Some(Ordering::Equal), - (Expiration::Never {}, _) => Some(Ordering::Greater), - (_, Expiration::Never {}) => Some(Ordering::Less), - // if they are mis-matched finite ends, no compare possible - _ => None, - } - } -} - -pub const HOUR: Duration = Duration::Time(60 * 60); -pub const DAY: Duration = Duration::Time(24 * 60 * 60); -pub const WEEK: Duration = Duration::Time(7 * 24 * 60 * 60); - -/// Duration is a delta of time. You can add it to a BlockInfo or Expiration to -/// move that further in the future. Note that an height-based Duration and -/// a time-based Expiration cannot be combined -#[cw_serde] -#[derive(Copy)] -pub enum Duration { - Height(u64), - /// Time in seconds - Time(u64), -} - -impl fmt::Display for Duration { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Duration::Height(height) => write!(f, "height: {}", height), - Duration::Time(time) => write!(f, "time: {}", time), - } - } -} - -impl Duration { - /// Create an expiration for Duration after current block - pub fn after(&self, block: &BlockInfo) -> Expiration { - match self { - Duration::Height(h) => Expiration::AtHeight(block.height + h), - Duration::Time(t) => Expiration::AtTime(block.time.plus_seconds(*t)), - } - } - - // creates a number just a little bigger, so we can use it to pass expiration point - pub fn plus_one(&self) -> Duration { - match self { - Duration::Height(h) => Duration::Height(h + 1), - Duration::Time(t) => Duration::Time(t + 1), - } - } -} - -impl Add for Duration { - type Output = StdResult; - - fn add(self, rhs: Duration) -> StdResult { - match (self, rhs) { - (Duration::Time(t), Duration::Time(t2)) => Ok(Duration::Time(t + t2)), - (Duration::Height(h), Duration::Height(h2)) => Ok(Duration::Height(h + h2)), - _ => Err(StdError::generic_err("Cannot add height and time")), - } - } -} - -impl Mul for Duration { - type Output = Duration; - - fn mul(self, rhs: u64) -> Self::Output { - match self { - Duration::Time(t) => Duration::Time(t * rhs), - Duration::Height(h) => Duration::Height(h * rhs), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn compare_expiration() { - // matching pairs - assert!(Expiration::AtHeight(5) < Expiration::AtHeight(10)); - assert!(Expiration::AtHeight(8) > Expiration::AtHeight(7)); - assert!( - Expiration::AtTime(Timestamp::from_seconds(555)) - < Expiration::AtTime(Timestamp::from_seconds(777)) - ); - assert!( - Expiration::AtTime(Timestamp::from_seconds(86)) - < Expiration::AtTime(Timestamp::from_seconds(100)) - ); - - // never as infinity - assert!(Expiration::AtHeight(500000) < Expiration::Never {}); - assert!(Expiration::Never {} > Expiration::AtTime(Timestamp::from_seconds(500000))); - - // what happens for the uncomparables?? all compares are false - assert_eq!( - None, - Expiration::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Expiration::AtHeight(230)) - ); - assert_eq!( - Expiration::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Expiration::AtHeight(230)), - None - ); - assert_eq!( - Expiration::AtTime(Timestamp::from_seconds(1000)) - .partial_cmp(&Expiration::AtHeight(230)), - None - ); - assert!(!(Expiration::AtTime(Timestamp::from_seconds(1000)) == Expiration::AtHeight(230))); - } - - #[test] - fn expiration_addition() { - // height - let end = Expiration::AtHeight(12345) + Duration::Height(400); - assert_eq!(end.unwrap(), Expiration::AtHeight(12745)); - - // time - let end = Expiration::AtTime(Timestamp::from_seconds(55544433)) + Duration::Time(40300); - assert_eq!( - end.unwrap(), - Expiration::AtTime(Timestamp::from_seconds(55584733)) - ); - - // never - let end = Expiration::Never {} + Duration::Time(40300); - assert_eq!(end.unwrap(), Expiration::Never {}); - - // mismatched - let end = Expiration::AtHeight(12345) + Duration::Time(1500); - end.unwrap_err(); - - // // not possible other way - // let end = Duration::Time(1000) + Expiration::AtTime(50000); - // assert_eq!(end.unwrap(), Expiration::AtTime(51000)); - } - - #[test] - fn block_plus_duration() { - let block = BlockInfo { - height: 1000, - time: Timestamp::from_seconds(7777), - chain_id: "foo".to_string(), - }; - - let end = Duration::Height(456).after(&block); - assert_eq!(Expiration::AtHeight(1456), end); - - let end = Duration::Time(1212).after(&block); - assert_eq!(Expiration::AtTime(Timestamp::from_seconds(8989)), end); - } - - #[test] - fn duration_math() { - let long = (Duration::Height(444) + Duration::Height(555)).unwrap(); - assert_eq!(Duration::Height(999), long); - - let days = DAY * 3; - assert_eq!(Duration::Time(3 * 24 * 60 * 60), days); - } -} diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs deleted file mode 100644 index d88e65921..000000000 --- a/packages/utils/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -/*! -This is a collection of common types shared among many specs. -For example [`Expiration`], which is embedded in many places. - -Types should only be added here after they are duplicated in -a second contract, not "because we might need it" -*/ - -mod balance; -mod event; -mod expiration; -mod migrate; -mod pagination; -mod parse_reply; -mod payment; -mod scheduled; -mod threshold; - -pub use migrate::ensure_from_older_version; -pub use pagination::{ - calc_range_end, calc_range_start, calc_range_start_string, maybe_addr, maybe_canonical, -}; -pub use parse_reply::{ - parse_execute_response_data, parse_instantiate_response_data, parse_reply_execute_data, - parse_reply_instantiate_data, MsgExecuteContractResponse, MsgInstantiateContractResponse, - ParseReplyError, -}; -pub use payment::{may_pay, must_pay, nonpayable, one_coin, PaymentError}; -pub use threshold::{Threshold, ThresholdError, ThresholdResponse}; - -pub use crate::balance::NativeBalance; -pub use crate::event::Event; -pub use crate::expiration::{Duration, Expiration, DAY, HOUR, WEEK}; -pub use crate::scheduled::Scheduled; diff --git a/packages/utils/src/migrate.rs b/packages/utils/src/migrate.rs deleted file mode 100644 index e537cba5a..000000000 --- a/packages/utils/src/migrate.rs +++ /dev/null @@ -1,100 +0,0 @@ -use cosmwasm_std::{StdError, StdResult, Storage}; -use cw2::{get_contract_version, set_contract_version}; -use semver::Version; - -/// This function not only validates that the right contract and version can be migrated, but also -/// updates the contract version from the original (stored) version to the new version. -/// It returns the original version for the convenience of doing external checks. -pub fn ensure_from_older_version( - storage: &mut dyn Storage, - name: &str, - new_version: &str, -) -> StdResult { - let version: Version = new_version.parse().map_err(from_semver)?; - let stored = get_contract_version(storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - if name != stored.contract { - let msg = format!("Cannot migrate from {} to {}", stored.contract, name); - return Err(StdError::generic_err(msg)); - } - - if storage_version > version { - let msg = format!( - "Cannot migrate from newer version ({}) to older ({})", - stored.version, new_version - ); - return Err(StdError::generic_err(msg)); - } - if storage_version < version { - // we don't need to save anything if migrating from the same version - set_contract_version(storage, name, new_version)?; - } - - Ok(storage_version) -} - -fn from_semver(err: semver::Error) -> StdError { - StdError::generic_err(format!("Semver: {}", err)) -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn accepts_identical_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); - // ensure this matches - ensure_from_older_version(&mut storage, "demo", "0.1.2").unwrap(); - } - - #[test] - fn accepts_and_updates_on_newer_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.4.0").unwrap(); - // ensure this matches - let original_version = ensure_from_older_version(&mut storage, "demo", "0.4.2").unwrap(); - - // check the original version is returned - assert_eq!(original_version.to_string(), "0.4.0".to_string()); - - // check the version is updated - let stored = get_contract_version(&storage).unwrap(); - assert_eq!(stored.contract, "demo".to_string()); - assert_eq!(stored.version, "0.4.2".to_string()); - } - - #[test] - fn errors_on_name_mismatch() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); - // ensure this matches - let err = ensure_from_older_version(&mut storage, "cw20-base", "0.1.2").unwrap_err(); - assert!(err.to_string().contains("cw20-base"), "{}", err); - assert!(err.to_string().contains("demo"), "{}", err); - } - - #[test] - fn errors_on_older_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.10.2").unwrap(); - // ensure this matches - let err = ensure_from_older_version(&mut storage, "demo", "0.9.7").unwrap_err(); - assert!(err.to_string().contains("0.10.2"), "{}", err); - assert!(err.to_string().contains("0.9.7"), "{}", err); - } - - #[test] - fn errors_on_broken_version() { - let mut storage = MockStorage::new(); - let err = ensure_from_older_version(&mut storage, "demo", "0.a.7").unwrap_err(); - assert!( - err.to_string().contains("unexpected character 'a'"), - "{}", - err - ); - } -} diff --git a/packages/utils/src/pagination.rs b/packages/utils/src/pagination.rs deleted file mode 100644 index a88996acb..000000000 --- a/packages/utils/src/pagination.rs +++ /dev/null @@ -1,115 +0,0 @@ -use cosmwasm_std::{Addr, Api, CanonicalAddr, StdResult}; - -// this is used for pagination. Maybe we move it into the std lib one day? -pub fn maybe_canonical(api: &dyn Api, human: Option) -> StdResult> { - human.map(|x| api.addr_canonicalize(x.as_ref())).transpose() -} - -// This is used for pagination. Maybe we move it into the std lib one day? -pub fn maybe_addr(api: &dyn Api, human: Option) -> StdResult> { - human.map(|x| api.addr_validate(&x)).transpose() -} - -// this will set the first key after the provided key, by appending a 0 byte -pub fn calc_range_start(start_after: Option) -> Option> { - start_after.map(|addr| { - let mut v: Vec = addr.as_bytes().into(); - v.push(0); - v - }) -} - -// set the end to the canonicalized format (used for Order::Descending) -pub fn calc_range_end(end_before: Option) -> Option> { - end_before.map(|addr| addr.as_bytes().into()) -} - -// this will set the first key after the provided key, by appending a 0 byte -pub fn calc_range_start_string(start_after: Option) -> Option> { - start_after.map(|token_id| { - let mut v: Vec = token_id.into_bytes(); - v.push(0); - v - }) -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::{testing::mock_dependencies, Order}; - use cw_storage_plus::{Bound, Map}; - - pub const HOLDERS: Map<&Addr, usize> = Map::new("some_data"); - const LIMIT: usize = 30; - - fn addr_from_i(i: usize) -> Addr { - Addr::unchecked(format!("addr{:0>8}", i)) - } - - #[test] - fn calc_range_start_works_as_expected() { - let total_elements_count = 100; - let mut deps = mock_dependencies(); - for i in 0..total_elements_count { - let holder = (addr_from_i(i), i); - HOLDERS - .save(&mut deps.storage, &holder.0, &holder.1) - .unwrap(); - } - - for j in 0..4 { - let start_after = if j == 0 { - None - } else { - Some(addr_from_i(j * LIMIT - 1)) - }; - - let start = calc_range_start(start_after).map(Bound::ExclusiveRaw); - - let holders = HOLDERS - .keys(&deps.storage, start, None, Order::Ascending) - .take(LIMIT) - .collect::>>() - .unwrap(); - - for (i, holder) in holders.into_iter().enumerate() { - let global_index = j * LIMIT + i; - assert_eq!(holder, addr_from_i(global_index)); - } - } - } - - #[test] - fn calc_range_end_works_as_expected() { - let total_elements_count = 100; - let mut deps = mock_dependencies(); - for i in 0..total_elements_count { - let holder = (addr_from_i(i), i); - HOLDERS - .save(&mut deps.storage, &holder.0, &holder.1) - .unwrap(); - } - - 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::ExclusiveRaw); - - let holders = HOLDERS - .keys(&deps.storage, None, end, Order::Descending) - .take(LIMIT) - .collect::>>() - .unwrap(); - - for (i, holder) in holders.into_iter().enumerate() { - let global_index = total_elements_count - i - j * LIMIT - 1; - assert_eq!(holder, addr_from_i(global_index)); - } - } - } - - // TODO: add unit tests - #[ignore] - #[test] - fn add_more_tests() {} -} diff --git a/packages/utils/src/parse_reply.rs b/packages/utils/src/parse_reply.rs deleted file mode 100644 index f52d18933..000000000 --- a/packages/utils/src/parse_reply.rs +++ /dev/null @@ -1,528 +0,0 @@ -use thiserror::Error; - -use cosmwasm_std::{Binary, Reply}; - -// Protobuf wire types (https://developers.google.com/protocol-buffers/docs/encoding) -const WIRE_TYPE_LENGTH_DELIMITED: u8 = 2; -// Up to 9 bytes of varints as a practical limit (https://github.com/multiformats/unsigned-varint#practical-maximum-of-9-bytes-for-security) -const VARINT_MAX_BYTES: usize = 9; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct MsgInstantiateContractResponse { - pub contract_address: String, - pub data: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct MsgExecuteContractResponse { - pub data: Option, -} - -/// Base128 varint decoding. -/// The remaining of the data is kept in the data parameter. -fn parse_protobuf_varint(data: &mut Vec, field_number: u8) -> Result { - let data_len = data.len(); - let mut len: u64 = 0; - let mut i = 0; - while i < VARINT_MAX_BYTES { - if data_len == i { - return Err(ParseReplyError::ParseFailure(format!( - "failed to decode Protobuf message: field #{}: varint data too short", - field_number - ))); - } - len += ((data[i] & 0x7f) as u64) << (i * 7); - if data[i] & 0x80 == 0 { - break; - } - i += 1; - } - if i == VARINT_MAX_BYTES { - return Err(ParseReplyError::ParseFailure(format!( - "failed to decode Protobuf message: field #{}: varint data too long", - field_number - ))); - } - *data = data[i + 1..].to_owned(); - - Ok(len as usize) // Gently fall back to the arch's max addressable size -} - -/// Helper function to parse length-prefixed protobuf fields. -/// The remaining of the data is kept in the data parameter. -fn parse_protobuf_length_prefixed( - data: &mut Vec, - field_number: u8, -) -> Result, ParseReplyError> { - if data.is_empty() { - return Ok(vec![]); - }; - let mut rest_1 = data.split_off(1); - let wire_type = data[0] & 0b11; - let field = data[0] >> 3; - - if field != field_number { - return Err(ParseReplyError::ParseFailure(format!( - "failed to decode Protobuf message: invalid field #{} for field #{}", - field, field_number - ))); - } - if wire_type != WIRE_TYPE_LENGTH_DELIMITED { - return Err(ParseReplyError::ParseFailure(format!( - "failed to decode Protobuf message: field #{}: invalid wire type {}", - field_number, wire_type - ))); - } - - let len = parse_protobuf_varint(&mut rest_1, field_number)?; - if rest_1.len() < len { - return Err(ParseReplyError::ParseFailure(format!( - "failed to decode Protobuf message: field #{}: message too short", - field_number - ))); - } - *data = rest_1.split_off(len); - - Ok(rest_1) -} - -fn parse_protobuf_string(data: &mut Vec, field_number: u8) -> Result { - let str_field = parse_protobuf_length_prefixed(data, field_number)?; - Ok(String::from_utf8(str_field)?) -} - -fn parse_protobuf_bytes( - data: &mut Vec, - field_number: u8, -) -> Result, ParseReplyError> { - let bytes_field = parse_protobuf_length_prefixed(data, field_number)?; - if bytes_field.is_empty() { - Ok(None) - } else { - Ok(Some(Binary(bytes_field))) - } -} - -pub fn parse_reply_instantiate_data( - msg: Reply, -) -> Result { - let data = msg - .result - .into_result() - .map_err(ParseReplyError::SubMsgFailure)? - .data - .ok_or_else(|| ParseReplyError::ParseFailure("Missing reply data".to_owned()))?; - parse_instantiate_response_data(&data.0) -} - -pub fn parse_reply_execute_data(msg: Reply) -> Result { - let data = msg - .result - .into_result() - .map_err(ParseReplyError::SubMsgFailure)? - .data - .ok_or_else(|| ParseReplyError::ParseFailure("Missing reply data".to_owned()))?; - parse_execute_response_data(&data.0) -} - -pub fn parse_instantiate_response_data( - data: &[u8], -) -> Result { - // Manual protobuf decoding - let mut data = data.to_vec(); - // Parse contract addr - let contract_addr = parse_protobuf_string(&mut data, 1)?; - - // Parse (optional) data - let data = parse_protobuf_bytes(&mut data, 2)?; - - Ok(MsgInstantiateContractResponse { - contract_address: contract_addr, - data, - }) -} - -pub fn parse_execute_response_data( - data: &[u8], -) -> Result { - // Manual protobuf decoding - let mut data = data.to_vec(); - let inner_data = parse_protobuf_bytes(&mut data, 1)?; - - Ok(MsgExecuteContractResponse { data: inner_data }) -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum ParseReplyError { - #[error("Failure response from sub-message: {0}")] - SubMsgFailure(String), - - #[error("Invalid reply from sub-message: {0}")] - ParseFailure(String), - - #[error("Error occurred while converting from UTF-8")] - BrokenUtf8(#[from] std::string::FromUtf8Error), -} - -#[cfg(test)] -mod test { - use super::*; - use crate::parse_reply::ParseReplyError::{BrokenUtf8, ParseFailure}; - use cosmwasm_std::{SubMsgResponse, SubMsgResult}; - use prost::Message; - use std::str::from_utf8; - - fn encode_bytes(data: &[u8]) -> Vec { - #[derive(Clone, PartialEq, Message)] - struct ProtobufBytes { - #[prost(bytes, tag = "1")] - pub data: Vec, - } - - let data = ProtobufBytes { - data: data.to_vec(), - }; - let mut encoded_data = Vec::::with_capacity(data.encoded_len()); - data.encode(&mut encoded_data).unwrap(); - - encoded_data - } - - fn encode_string(data: &str) -> Vec { - #[derive(Clone, PartialEq, Message)] - struct ProtobufString { - #[prost(string, tag = "1")] - pub data: String, - } - - let data = ProtobufString { - data: data.to_string(), - }; - let mut encoded_data = Vec::::with_capacity(data.encoded_len()); - data.encode(&mut encoded_data).unwrap(); - - encoded_data - } - - #[derive(Clone, PartialEq, Message)] - struct MsgInstantiateContractResponse { - #[prost(string, tag = "1")] - pub contract_address: ::prost::alloc::string::String, - #[prost(bytes, tag = "2")] - pub data: ::prost::alloc::vec::Vec, - } - - #[derive(Clone, PartialEq, Message)] - struct MsgExecuteContractResponse { - #[prost(bytes, tag = "1")] - pub data: ::prost::alloc::vec::Vec, - } - - #[test] - fn parse_protobuf_varint_tests() { - let field_number = 1; - // Single-byte varint works - let mut data = b"\x0a".to_vec(); - let len = parse_protobuf_varint(&mut data, field_number).unwrap(); - assert_eq!(len, 10); - - // Rest is returned - let mut data = b"\x0a\x0b".to_vec(); - let len = parse_protobuf_varint(&mut data, field_number).unwrap(); - assert_eq!(len, 10); - assert_eq!(data, b"\x0b".to_vec()); - - // Multi-byte varint works - // 300 % 128 = 44. 44 + 128 = 172 (0xac) (1st byte) - // 300 / 128 = 2 (x02) (2nd byte) - let mut data = b"\xac\x02".to_vec(); - let len = parse_protobuf_varint(&mut data, field_number).unwrap(); - assert_eq!(len, 300); - - // Rest is returned - let mut data = b"\xac\x02\x0c".to_vec(); - let len = parse_protobuf_varint(&mut data, field_number).unwrap(); - assert_eq!(len, 300); - assert_eq!(data, b"\x0c".to_vec()); - - // varint data too short (Empty varint) - let mut data = vec![]; - let err = parse_protobuf_varint(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - - // varint data too short (Incomplete varint) - let mut data = b"\x80".to_vec(); - let err = parse_protobuf_varint(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - - // varint data too long - let mut data = b"\x80\x81\x82\x83\x84\x83\x82\x81\x80".to_vec(); - let err = parse_protobuf_varint(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - } - - #[test] - fn parse_protobuf_length_prefixed_tests() { - let field_number = 1; - // Single-byte length-prefixed works - let mut data = b"\x0a\x03abc".to_vec(); - let res = parse_protobuf_length_prefixed(&mut data, field_number).unwrap(); - assert_eq!(res, b"abc".to_vec()); - assert_eq!(data, vec![0u8; 0]); - - // Rest is returned - let mut data = b"\x0a\x03abcd".to_vec(); - let res = parse_protobuf_length_prefixed(&mut data, field_number).unwrap(); - assert_eq!(res, b"abc".to_vec()); - assert_eq!(data, b"d".to_vec()); - - // Multi-byte length-prefixed works - let mut data = [b"\x0a\xac\x02", vec![65u8; 300].as_slice()] - .concat() - .to_vec(); - let res = parse_protobuf_length_prefixed(&mut data, field_number).unwrap(); - assert_eq!(res, vec![65u8; 300]); - assert_eq!(data, vec![0u8; 0]); - - // Rest is returned - let mut data = [b"\x0a\xac\x02", vec![65u8; 300].as_slice(), b"rest"] - .concat() - .to_vec(); - let res = parse_protobuf_length_prefixed(&mut data, field_number).unwrap(); - assert_eq!(res, vec![65u8; 300]); - assert_eq!(data, b"rest"); - - // message too short - let mut data = b"\x0a\x01".to_vec(); - let field_number = 1; - let err = parse_protobuf_length_prefixed(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - - // invalid wire type - let mut data = b"\x0b\x01a".to_vec(); - let err = parse_protobuf_length_prefixed(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - - // invalid field number - let field_number = 2; - let mut data = b"\x0a\x01a".to_vec(); - let err = parse_protobuf_length_prefixed(&mut data, field_number).unwrap_err(); - assert!(matches!(err, ParseFailure(..))); - } - - #[test] - fn parse_protobuf_bytes_works() { - let field_number = 1; - - // Empty works - let data = vec![]; - let mut encoded_data = encode_bytes(&data); - - let res = parse_protobuf_bytes(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, None); - - // Simple works - let data = b"test".to_vec(); - let mut encoded_data = encode_bytes(&data); - - let res = parse_protobuf_bytes(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, Some(Binary(data))); - - // Large works - let data = vec![0x40; 300]; - let mut encoded_data = encode_bytes(&data); - - let res = parse_protobuf_bytes(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, Some(Binary(data))); - - // Field number works - let field_number = 5; - let data = b"test field 5".to_vec(); - let mut encoded_data = encode_bytes(&data); - encoded_data[0] = (field_number << 3) + WIRE_TYPE_LENGTH_DELIMITED; - - let res = parse_protobuf_bytes(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, Some(Binary(data))); - - // Remainder is kept - let field_number = 1; - let test_len: usize = 4; - let data = b"test_remainder".to_vec(); - let mut encoded_data = encode_bytes(&data); - encoded_data[1] = test_len as u8; - - let res = parse_protobuf_bytes(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, Some(Binary(data[..test_len].to_owned()))); - assert_eq!(encoded_data, data[test_len..].to_owned()); - } - - #[test] - fn parse_protobuf_string_tests() { - let field_number = 1; - - // Empty works - let data = ""; - let mut encoded_data = encode_string(data); - - let res = parse_protobuf_string(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, data); - - // Simple works - let data = "test"; - let mut encoded_data = encode_string(data); - - let res = parse_protobuf_string(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, data); - - // Large works - let data = vec![0x40; 300]; - let str_data = from_utf8(data.as_slice()).unwrap(); - let mut encoded_data = encode_string(str_data); - - let res = parse_protobuf_string(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, str_data); - - // Field number works - let field_number = 5; - let data = "test field 5"; - let mut encoded_data = encode_string(data); - encoded_data[0] = (field_number << 3) + WIRE_TYPE_LENGTH_DELIMITED; - - let res = parse_protobuf_string(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, data); - - // Remainder is kept - let field_number = 1; - let test_len: usize = 4; - let data = "test_remainder"; - let mut encoded_data = encode_string(data); - encoded_data[1] = test_len as u8; - - let res = parse_protobuf_string(&mut encoded_data, field_number).unwrap(); - assert_eq!(res, data[..test_len]); - assert_eq!(encoded_data, data[test_len..].as_bytes()); - - // Broken utf-8 errs - let field_number = 1; - let data = "test_X"; - let mut encoded_data = encode_string(data); - let encoded_len = encoded_data.len(); - encoded_data[encoded_len - 1] = 0xd3; - let err = parse_protobuf_string(&mut encoded_data, field_number).unwrap_err(); - assert!(matches!(err, BrokenUtf8(..))); - } - - #[test] - fn parse_reply_instantiate_data_works() { - let contract_addr: &str = "Contract #1"; - for (data, expected) in [ - ( - vec![], - super::MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data: None, - }, - ), - ( - vec![1u8, 2, 255, 7, 5], - super::MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data: Some(Binary(vec![1u8, 2, 255, 7, 5])), - }, - ), - ( - vec![1u8; 127], - super::MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data: Some(Binary(vec![1u8; 127])), - }, - ), - ( - vec![2u8; 128], - super::MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data: Some(Binary(vec![2u8; 128])), - }, - ), - ( - vec![3u8; 257], - super::MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data: Some(Binary(vec![3u8; 257])), - }, - ), - ] { - let instantiate_reply = MsgInstantiateContractResponse { - contract_address: contract_addr.to_string(), - data, - }; - let mut encoded_instantiate_reply = - Vec::::with_capacity(instantiate_reply.encoded_len()); - // The data must encode successfully - instantiate_reply - .encode(&mut encoded_instantiate_reply) - .unwrap(); - - // Build reply message - let msg = Reply { - id: 1, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: Some(encoded_instantiate_reply.into()), - }), - }; - - let res = parse_reply_instantiate_data(msg).unwrap(); - assert_eq!(res, expected); - } - } - - #[test] - fn parse_reply_execute_data_works() { - for (data, expected) in [ - (vec![], super::MsgExecuteContractResponse { data: None }), - ( - vec![1u8, 2, 3, 127, 15], - super::MsgExecuteContractResponse { - data: Some(Binary(vec![1u8, 2, 3, 127, 15])), - }, - ), - ( - vec![0u8; 255], - super::MsgExecuteContractResponse { - data: Some(Binary(vec![0u8; 255])), - }, - ), - ( - vec![1u8; 256], - super::MsgExecuteContractResponse { - data: Some(Binary(vec![1u8; 256])), - }, - ), - ( - vec![2u8; 32769], - super::MsgExecuteContractResponse { - data: Some(Binary(vec![2u8; 32769])), - }, - ), - ] { - let execute_reply = MsgExecuteContractResponse { data }; - let mut encoded_execute_reply = Vec::::with_capacity(execute_reply.encoded_len()); - // The data must encode successfully - execute_reply.encode(&mut encoded_execute_reply).unwrap(); - - // Build reply message - let msg = Reply { - id: 1, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: Some(encoded_execute_reply.into()), - }), - }; - - let res = parse_reply_execute_data(msg).unwrap(); - - assert_eq!(res, expected); - } - } -} diff --git a/packages/utils/src/payment.rs b/packages/utils/src/payment.rs deleted file mode 100644 index f6ccdd201..000000000 --- a/packages/utils/src/payment.rs +++ /dev/null @@ -1,136 +0,0 @@ -use cosmwasm_std::{Coin, MessageInfo, Uint128}; -use thiserror::Error; - -/// returns an error if any coins were sent -pub fn nonpayable(info: &MessageInfo) -> Result<(), PaymentError> { - if info.funds.is_empty() { - Ok(()) - } else { - Err(PaymentError::NonPayable {}) - } -} - -/// If exactly one coin was sent, returns it regardless of denom. -/// Returns error if 0 or 2+ coins were sent -pub fn one_coin(info: &MessageInfo) -> Result { - match info.funds.len() { - 0 => Err(PaymentError::NoFunds {}), - 1 => { - let coin = &info.funds[0]; - if coin.amount.is_zero() { - Err(PaymentError::NoFunds {}) - } else { - Ok(coin.clone()) - } - } - _ => Err(PaymentError::MultipleDenoms {}), - } -} - -/// Requires exactly one denom sent, which matches the requested denom. -/// Returns the amount if only one denom and non-zero amount. Errors otherwise. -pub fn must_pay(info: &MessageInfo, denom: &str) -> Result { - let coin = one_coin(info)?; - if coin.denom != denom { - Err(PaymentError::MissingDenom(denom.to_string())) - } else { - Ok(coin.amount) - } -} - -/// Similar to must_pay, but it any payment is optional. Returns an error if a different -/// denom was sent. Otherwise, returns the amount of `denom` sent, or 0 if nothing sent. -pub fn may_pay(info: &MessageInfo, denom: &str) -> Result { - if info.funds.is_empty() { - Ok(Uint128::zero()) - } else if info.funds.len() == 1 && info.funds[0].denom == denom { - Ok(info.funds[0].amount) - } else { - // find first mis-match - let wrong = info.funds.iter().find(|c| c.denom != denom).unwrap(); - Err(PaymentError::ExtraDenom(wrong.denom.to_string())) - } -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum PaymentError { - #[error("Must send reserve token '{0}'")] - MissingDenom(String), - - #[error("Received unsupported denom '{0}'")] - ExtraDenom(String), - - #[error("Sent more than one denomination")] - MultipleDenoms {}, - - #[error("No funds sent")] - NoFunds {}, - - #[error("This message does no accept funds")] - NonPayable {}, -} - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{coin, coins}; - - const SENDER: &str = "sender"; - - #[test] - fn nonpayable_works() { - let no_payment = mock_info(SENDER, &[]); - nonpayable(&no_payment).unwrap(); - - let payment = mock_info(SENDER, &coins(100, "uatom")); - let res = nonpayable(&payment); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}); - } - - #[test] - fn may_pay_works() { - let atom: &str = "uatom"; - let no_payment = mock_info(SENDER, &[]); - let atom_payment = mock_info(SENDER, &coins(100, atom)); - let eth_payment = mock_info(SENDER, &coins(100, "wei")); - let mixed_payment = mock_info(SENDER, &[coin(50, atom), coin(120, "wei")]); - - let res = may_pay(&no_payment, atom).unwrap(); - assert_eq!(res, Uint128::zero()); - - let res = may_pay(&atom_payment, atom).unwrap(); - assert_eq!(res, Uint128::new(100)); - - let err = may_pay(ð_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::ExtraDenom("wei".to_string())); - - let err = may_pay(&mixed_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::ExtraDenom("wei".to_string())); - } - - #[test] - fn must_pay_works() { - let atom: &str = "uatom"; - let no_payment = mock_info(SENDER, &[]); - let atom_payment = mock_info(SENDER, &coins(100, atom)); - let zero_payment = mock_info(SENDER, &coins(0, atom)); - let eth_payment = mock_info(SENDER, &coins(100, "wei")); - let mixed_payment = mock_info(SENDER, &[coin(50, atom), coin(120, "wei")]); - - let res = must_pay(&atom_payment, atom).unwrap(); - assert_eq!(res, Uint128::new(100)); - - let err = must_pay(&no_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::NoFunds {}); - - let err = must_pay(&zero_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::NoFunds {}); - - let err = must_pay(ð_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::MissingDenom(atom.to_string())); - - let err = must_pay(&mixed_payment, atom).unwrap_err(); - assert_eq!(err, PaymentError::MultipleDenoms {}); - } -} diff --git a/packages/utils/src/scheduled.rs b/packages/utils/src/scheduled.rs deleted file mode 100644 index f96794cdb..000000000 --- a/packages/utils/src/scheduled.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::Duration; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{BlockInfo, StdError, StdResult, Timestamp}; -use std::cmp::Ordering; -use std::fmt; -use std::ops::Add; - -/// Scheduled represents a point in time when an event happens. -/// It can compare with a BlockInfo and will return is_triggered() == true -/// once the condition is hit (and for every block in the future) -#[cw_serde] -#[derive(Copy)] -pub enum Scheduled { - /// AtHeight will schedule when `env.block.height` >= height - AtHeight(u64), - /// AtTime will schedule when `env.block.time` >= time - AtTime(Timestamp), -} - -impl fmt::Display for Scheduled { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Scheduled::AtHeight(height) => write!(f, "scheduled height: {}", height), - Scheduled::AtTime(time) => write!(f, "scheduled time: {}", time), - } - } -} - -impl Scheduled { - #[allow(dead_code)] - pub fn is_triggered(&self, block: &BlockInfo) -> bool { - match self { - Scheduled::AtHeight(height) => block.height >= *height, - Scheduled::AtTime(time) => block.time >= *time, - } - } -} - -impl Add for Scheduled { - type Output = StdResult; - - fn add(self, duration: Duration) -> StdResult { - match (self, duration) { - (Scheduled::AtTime(t), Duration::Time(delta)) => { - Ok(Scheduled::AtTime(t.plus_seconds(delta))) - } - (Scheduled::AtHeight(h), Duration::Height(delta)) => Ok(Scheduled::AtHeight(h + delta)), - _ => Err(StdError::generic_err("Cannot add height and time")), - } - } -} - -impl PartialOrd for Scheduled { - fn partial_cmp(&self, other: &Scheduled) -> Option { - match (self, other) { - // compare if both height or both time - (Scheduled::AtHeight(h1), Scheduled::AtHeight(h2)) => Some(h1.cmp(h2)), - (Scheduled::AtTime(t1), Scheduled::AtTime(t2)) => Some(t1.cmp(t2)), - _ => None, - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn compare_schedules() { - // matching pairs - assert!(Scheduled::AtHeight(5) < Scheduled::AtHeight(10)); - assert!(Scheduled::AtHeight(8) > Scheduled::AtHeight(7)); - assert!( - Scheduled::AtTime(Timestamp::from_seconds(555)) - < Scheduled::AtTime(Timestamp::from_seconds(777)) - ); - assert!( - Scheduled::AtTime(Timestamp::from_seconds(86)) - < Scheduled::AtTime(Timestamp::from_seconds(100)) - ); - - // what happens for the uncomparables?? all compares are false - assert_eq!( - None, - Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)) - ); - assert_eq!( - Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)), - None - ); - assert_eq!( - Scheduled::AtTime(Timestamp::from_seconds(1000)).partial_cmp(&Scheduled::AtHeight(230)), - None - ); - assert!(!(Scheduled::AtTime(Timestamp::from_seconds(1000)) == Scheduled::AtHeight(230))); - } - - #[test] - fn schedule_addition() { - // height - let end = Scheduled::AtHeight(12345) + Duration::Height(400); - assert_eq!(end.unwrap(), Scheduled::AtHeight(12745)); - - // time - let end = Scheduled::AtTime(Timestamp::from_seconds(55544433)) + Duration::Time(40300); - assert_eq!( - end.unwrap(), - Scheduled::AtTime(Timestamp::from_seconds(55584733)) - ); - - // mismatched - let end = Scheduled::AtHeight(12345) + Duration::Time(1500); - end.unwrap_err(); - } -} diff --git a/packages/utils/src/threshold.rs b/packages/utils/src/threshold.rs deleted file mode 100644 index 312a298e0..000000000 --- a/packages/utils/src/threshold.rs +++ /dev/null @@ -1,337 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Decimal, StdError}; -use thiserror::Error; - -/// This defines the different ways tallies can happen. -/// -/// The total_weight used for calculating success as well as the weights of each -/// individual voter used in tallying should be snapshotted at the beginning of -/// the block at which the proposal starts (this is likely the responsibility of a -/// correct cw4 implementation). -/// See also `ThresholdResponse` in the cw3 spec. -#[cw_serde] -pub enum Threshold { - /// Declares that a fixed weight of Yes votes is needed to pass. - /// See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details. - AbsoluteCount { weight: u64 }, - - /// Declares a percentage of the total weight that must cast Yes votes in order for - /// a proposal to pass. - /// See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details. - AbsolutePercentage { percentage: Decimal }, - - /// Declares a `quorum` of the total votes that must participate in the election in order - /// for the vote to be considered at all. - /// See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details. - ThresholdQuorum { threshold: Decimal, quorum: Decimal }, -} - -impl Threshold { - /// returns error if this is an unreachable value, - /// given a total weight of all members in the group - pub fn validate(&self, total_weight: u64) -> Result<(), ThresholdError> { - match self { - Threshold::AbsoluteCount { - weight: weight_needed, - } => { - if *weight_needed == 0 { - Err(ThresholdError::ZeroWeight {}) - } else if *weight_needed > total_weight { - Err(ThresholdError::UnreachableWeight {}) - } else { - Ok(()) - } - } - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => valid_threshold(percentage_needed), - Threshold::ThresholdQuorum { - threshold, - quorum: quroum, - } => { - valid_threshold(threshold)?; - valid_quorum(quroum) - } - } - } - - /// Creates a response from the saved data, just missing the total_weight info - pub fn to_response(&self, total_weight: u64) -> ThresholdResponse { - match self.clone() { - Threshold::AbsoluteCount { weight } => ThresholdResponse::AbsoluteCount { - weight, - total_weight, - }, - Threshold::AbsolutePercentage { percentage } => ThresholdResponse::AbsolutePercentage { - percentage, - total_weight, - }, - Threshold::ThresholdQuorum { threshold, quorum } => { - ThresholdResponse::ThresholdQuorum { - threshold, - quorum, - total_weight, - } - } - } - } -} - -/// Asserts that the 0.5 < percent <= 1.0 -fn valid_threshold(percent: &Decimal) -> Result<(), ThresholdError> { - if *percent > Decimal::percent(100) || *percent < Decimal::percent(50) { - Err(ThresholdError::InvalidThreshold {}) - } else { - Ok(()) - } -} - -/// Asserts that the 0.5 < percent <= 1.0 -fn valid_quorum(percent: &Decimal) -> Result<(), ThresholdError> { - if percent.is_zero() { - Err(ThresholdError::ZeroQuorumThreshold {}) - } else if *percent > Decimal::one() { - Err(ThresholdError::UnreachableQuorumThreshold {}) - } else { - Ok(()) - } -} - -/// This defines the different ways tallies can happen. -/// Every contract should support a subset of these, ideally all. -/// -/// The total_weight used for calculating success as well as the weights of each -/// individual voter used in tallying should be snapshotted at the beginning of -/// the block at which the proposal starts (this is likely the responsibility of a -/// correct cw4 implementation). -#[cw_serde] -pub enum ThresholdResponse { - /// Declares that a fixed weight of yes votes is needed to pass. - /// It does not matter how many no votes are cast, or how many do not vote, - /// as long as `weight` yes votes are cast. - /// - /// This is the simplest format and usually suitable for small multisigs of trusted parties, - /// like 3 of 5. (weight: 3, total_weight: 5) - /// - /// A proposal of this type can pass early as soon as the needed weight of yes votes has been cast. - AbsoluteCount { weight: u64, total_weight: u64 }, - - /// Declares a percentage of the total weight that must cast Yes votes, in order for - /// a proposal to pass. The passing weight is computed over the total weight minus the weight of the - /// abstained votes. - /// - /// This is useful for similar circumstances as `AbsoluteCount`, where we have a relatively - /// small set of voters, and participation is required. - /// It is understood that if the voting set (group) changes between different proposals that - /// refer to the same group, each proposal will work with a different set of voter weights - /// (the ones snapshotted at proposal creation), and the passing weight for each proposal - /// will be computed based on the absolute percentage, times the total weights of the members - /// at the time of each proposal creation. - /// - /// Example: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. - /// This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the - /// `total_weight` of the group has increased to 9. That proposal will then automatically - /// require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`. - AbsolutePercentage { - percentage: Decimal, - total_weight: u64, - }, - - /// In addition to a `threshold`, declares a `quorum` of the total votes that must participate - /// in the election in order for the vote to be considered at all. Within the votes that - /// were cast, it requires `threshold` votes in favor. That is calculated by ignoring - /// the Abstain votes (they count towards `quorum`, but do not influence `threshold`). - /// That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider - /// if the proposal was passed. - /// - /// It is rather difficult for a proposal of this type to pass early. That can only happen if - /// the required quorum has been already met, and there are already enough Yes votes for the - /// proposal to pass. - /// - /// 30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% - /// (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting - /// no => 30% yes + 50% no). Once the voting period has passed with no additional votes, - /// that same proposal would be considered successful if quorum <= 60% and threshold <= 75% - /// (percent in favor if we ignore abstain votes). - /// - /// This type is more common in general elections, where participation is often expected to - /// be low, and `AbsolutePercentage` would either be too high to pass anything, - /// or allow low percentages to pass, independently of if there was high participation in the - /// election or not. - ThresholdQuorum { - threshold: Decimal, - quorum: Decimal, - total_weight: u64, - }, -} - -#[derive(Error, Debug, PartialEq)] -pub enum ThresholdError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Invalid voting threshold percentage, must be in the 0.5-1.0 range")] - InvalidThreshold {}, - - #[error("Required quorum threshold cannot be zero")] - ZeroQuorumThreshold {}, - - #[error("Not possible to reach required quorum threshold")] - UnreachableQuorumThreshold {}, - - #[error("Required weight cannot be zero")] - ZeroWeight {}, - - #[error("Not possible to reach required (passing) weight")] - UnreachableWeight {}, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn validate_quorum_percentage() { - // TODO: test the error messages - - // 0 is never a valid percentage - let err = valid_quorum(&Decimal::zero()).unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::ZeroQuorumThreshold {}.to_string() - ); - - // 100% is - valid_quorum(&Decimal::one()).unwrap(); - - // 101% is not - let err = valid_quorum(&Decimal::percent(101)).unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::UnreachableQuorumThreshold {}.to_string() - ); - // not 100.1% - let err = valid_quorum(&Decimal::permille(1001)).unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::UnreachableQuorumThreshold {}.to_string() - ); - } - - #[test] - fn validate_threshold_percentage() { - // other values in between 0.5 and 1 are valid - valid_threshold(&Decimal::percent(51)).unwrap(); - valid_threshold(&Decimal::percent(67)).unwrap(); - valid_threshold(&Decimal::percent(99)).unwrap(); - let err = valid_threshold(&Decimal::percent(101)).unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::InvalidThreshold {}.to_string() - ); - } - - #[test] - fn validate_threshold() { - // absolute count ensures 0 < required <= total_weight - let err = Threshold::AbsoluteCount { weight: 0 } - .validate(5) - .unwrap_err(); - // TODO: remove to_string() when PartialEq implemented - assert_eq!(err.to_string(), ThresholdError::ZeroWeight {}.to_string()); - let err = Threshold::AbsoluteCount { weight: 6 } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::UnreachableWeight {}.to_string() - ); - - Threshold::AbsoluteCount { weight: 1 }.validate(5).unwrap(); - Threshold::AbsoluteCount { weight: 5 }.validate(5).unwrap(); - - // AbsolutePercentage just enforces valid_percentage (tested above) - let err = Threshold::AbsolutePercentage { - percentage: Decimal::zero(), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::InvalidThreshold {}.to_string() - ); - Threshold::AbsolutePercentage { - percentage: Decimal::percent(51), - } - .validate(5) - .unwrap(); - - // Quorum enforces both valid just enforces valid_percentage (tested above) - Threshold::ThresholdQuorum { - threshold: Decimal::percent(51), - quorum: Decimal::percent(40), - } - .validate(5) - .unwrap(); - let err = Threshold::ThresholdQuorum { - threshold: Decimal::percent(101), - quorum: Decimal::percent(40), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::InvalidThreshold {}.to_string() - ); - let err = Threshold::ThresholdQuorum { - threshold: Decimal::percent(51), - quorum: Decimal::percent(0), - } - .validate(5) - .unwrap_err(); - assert_eq!( - err.to_string(), - ThresholdError::ZeroQuorumThreshold {}.to_string() - ); - } - - #[test] - fn threshold_response() { - let total_weight: u64 = 100; - - let res = Threshold::AbsoluteCount { weight: 42 }.to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::AbsoluteCount { - weight: 42, - total_weight - } - ); - - let res = Threshold::AbsolutePercentage { - percentage: Decimal::percent(51), - } - .to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::AbsolutePercentage { - percentage: Decimal::percent(51), - total_weight - } - ); - - let res = Threshold::ThresholdQuorum { - threshold: Decimal::percent(66), - quorum: Decimal::percent(50), - } - .to_response(total_weight); - assert_eq!( - res, - ThresholdResponse::ThresholdQuorum { - threshold: Decimal::percent(66), - quorum: Decimal::percent(50), - total_weight - } - ); - } -} From 241959f5302d490abdffb1400cd153536b7e5cb7 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 18 Oct 2022 22:25:37 +0200 Subject: [PATCH 540/631] Remove cw1155 stuff --- Cargo.lock | 26 - contracts/cw1155-base/.cargo/config | 5 - contracts/cw1155-base/Cargo.toml | 29 - contracts/cw1155-base/README.md | 24 - contracts/cw1155-base/src/bin/schema.rs | 12 - contracts/cw1155-base/src/contract.rs | 109 ---- contracts/cw1155-base/src/error.rs | 14 - contracts/cw1155-base/src/execute.rs | 312 ----------- contracts/cw1155-base/src/helpers.rs | 30 - contracts/cw1155-base/src/lib.rs | 21 - contracts/cw1155-base/src/msg.rs | 9 - contracts/cw1155-base/src/query.rs | 130 ----- contracts/cw1155-base/src/state.rs | 13 - contracts/cw1155-base/src/tests.rs | 694 ------------------------ packages/cw1155/.cargo/config | 4 - packages/cw1155/Cargo.toml | 16 - packages/cw1155/README.md | 104 ---- packages/cw1155/src/bin/schema.rs | 22 - packages/cw1155/src/event.rs | 56 -- packages/cw1155/src/lib.rs | 30 - packages/cw1155/src/msg.rs | 67 --- packages/cw1155/src/query.rs | 94 ---- packages/cw1155/src/receiver.rs | 73 --- 23 files changed, 1894 deletions(-) delete mode 100644 contracts/cw1155-base/.cargo/config delete mode 100644 contracts/cw1155-base/Cargo.toml delete mode 100644 contracts/cw1155-base/README.md delete mode 100644 contracts/cw1155-base/src/bin/schema.rs delete mode 100644 contracts/cw1155-base/src/contract.rs delete mode 100644 contracts/cw1155-base/src/error.rs delete mode 100644 contracts/cw1155-base/src/execute.rs delete mode 100644 contracts/cw1155-base/src/helpers.rs delete mode 100644 contracts/cw1155-base/src/lib.rs delete mode 100644 contracts/cw1155-base/src/msg.rs delete mode 100644 contracts/cw1155-base/src/query.rs delete mode 100644 contracts/cw1155-base/src/state.rs delete mode 100644 contracts/cw1155-base/src/tests.rs delete mode 100644 packages/cw1155/.cargo/config delete mode 100644 packages/cw1155/Cargo.toml delete mode 100644 packages/cw1155/README.md delete mode 100644 packages/cw1155/src/bin/schema.rs delete mode 100644 packages/cw1155/src/event.rs delete mode 100644 packages/cw1155/src/lib.rs delete mode 100644 packages/cw1155/src/msg.rs delete mode 100644 packages/cw1155/src/query.rs delete mode 100644 packages/cw1155/src/receiver.rs diff --git a/Cargo.lock b/Cargo.lock index 3527aa4c4..cc4a30196 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,32 +291,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw1155" -version = "0.16.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "cw1155-base" -version = "0.16.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw1155", - "cw2 0.16.0", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "cw2" version = "0.16.0" diff --git a/contracts/cw1155-base/.cargo/config b/contracts/cw1155-base/.cargo/config deleted file mode 100644 index de2d36ac7..000000000 --- a/contracts/cw1155-base/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -wasm-debug = "build --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" diff --git a/contracts/cw1155-base/Cargo.toml b/contracts/cw1155-base/Cargo.toml deleted file mode 100644 index 1519faf63..000000000 --- a/contracts/cw1155-base/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "cw1155-base" -version = "0.16.0" -authors = ["Huang Yi "] -edition = "2018" -description = "Basic implementation of a CosmWasm-1155 compliant token" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all init/handle/query exports -library = [] - -[dependencies] -cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw1155 = { path = "../../packages/cw1155", version = "0.16.0" } -cw-storage-plus = "0.16.0" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.20" } diff --git a/contracts/cw1155-base/README.md b/contracts/cw1155-base/README.md deleted file mode 100644 index 6da195595..000000000 --- a/contracts/cw1155-base/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# CW1155 Basic - -This is a basic implementation of a cw1155 contract. -It implements the [CW1155 spec](../../packages/cw1155/README.md) and manages multiple tokens -(fungible or non-fungible) under one contract. - -## Instantiation - -To create it, you must pass in a `minter` address. - -```rust -#[cw_serde] -pub struct InstantiateMsg { - /// The minter is the only one who can create new tokens. - /// This is designed for a base token platform that is controlled by an external program or - /// contract. - pub minter: String, -} -``` - -## Messages - -All other messages and queries are defined by the -[CW1155 spec](../../packages/cw1155/README.md). Please refer to it for more info. \ No newline at end of file diff --git a/contracts/cw1155-base/src/bin/schema.rs b/contracts/cw1155-base/src/bin/schema.rs deleted file mode 100644 index a4c4d13d2..000000000 --- a/contracts/cw1155-base/src/bin/schema.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cosmwasm_schema::write_api; - -use cw1155::{Cw1155ExecuteMsg, Cw1155QueryMsg}; -use cw1155_base::msg::InstantiateMsg; - -fn main() { - write_api! { - instantiate: InstantiateMsg, - execute: Cw1155ExecuteMsg, - query: Cw1155QueryMsg, - } -} diff --git a/contracts/cw1155-base/src/contract.rs b/contracts/cw1155-base/src/contract.rs deleted file mode 100644 index eab6b12e8..000000000 --- a/contracts/cw1155-base/src/contract.rs +++ /dev/null @@ -1,109 +0,0 @@ -use crate::{error::ContractError, execute, msg::InstantiateMsg, query, state::MINTER}; -use cosmwasm_std::{ - entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, -}; -use cw1155::{Cw1155ExecuteMsg, Cw1155QueryMsg}; -use cw2::set_contract_version; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw1155-base"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> StdResult { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let minter = deps.api.addr_validate(&msg.minter)?; - MINTER.save(deps.storage, &minter)?; - Ok(Response::default()) -} - -/// To mitigate clippy::too_many_arguments warning -pub struct ExecuteEnv<'a> { - pub deps: DepsMut<'a>, - pub env: Env, - pub info: MessageInfo, -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: Cw1155ExecuteMsg, -) -> Result { - let env = ExecuteEnv { deps, env, info }; - match msg { - Cw1155ExecuteMsg::SendFrom { - from, - to, - token_id, - value, - msg, - } => execute::send_from(env, from, to, token_id, value, msg), - Cw1155ExecuteMsg::BatchSendFrom { - from, - to, - batch, - msg, - } => execute::batch_send_from(env, from, to, batch, msg), - Cw1155ExecuteMsg::Mint { - to, - token_id, - value, - msg, - } => execute::mint(env, to, token_id, value, msg), - Cw1155ExecuteMsg::BatchMint { to, batch, msg } => execute::batch_mint(env, to, batch, msg), - Cw1155ExecuteMsg::Burn { - from, - token_id, - value, - } => execute::burn(env, from, token_id, value), - Cw1155ExecuteMsg::BatchBurn { from, batch } => execute::batch_burn(env, from, batch), - Cw1155ExecuteMsg::ApproveAll { operator, expires } => { - execute::approve_all(env, operator, expires) - } - Cw1155ExecuteMsg::RevokeAll { operator } => execute::revoke_all(env, operator), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: Cw1155QueryMsg) -> StdResult { - match msg { - Cw1155QueryMsg::Balance { owner, token_id } => { - to_binary(&query::balance(deps, owner, token_id)?) - } - Cw1155QueryMsg::BatchBalance { owner, token_ids } => { - to_binary(&query::batch_balance(deps, owner, token_ids)?) - } - Cw1155QueryMsg::IsApprovedForAll { owner, operator } => { - to_binary(&query::is_approved_for_all(deps, env, owner, operator)?) - } - Cw1155QueryMsg::ApprovedForAll { - owner, - include_expired, - start_after, - limit, - } => to_binary(&query::approved_for_all( - deps, - env, - owner, - include_expired.unwrap_or(false), - start_after, - limit, - )?), - Cw1155QueryMsg::TokenInfo { token_id } => to_binary(&query::token_info(deps, token_id)?), - Cw1155QueryMsg::Tokens { - owner, - start_after, - limit, - } => to_binary(&query::tokens(deps, owner, start_after, limit)?), - Cw1155QueryMsg::AllTokens { start_after, limit } => { - to_binary(&query::all_tokens(deps, start_after, limit)?) - } - } -} diff --git a/contracts/cw1155-base/src/error.rs b/contracts/cw1155-base/src/error.rs deleted file mode 100644 index 109695593..000000000 --- a/contracts/cw1155-base/src/error.rs +++ /dev/null @@ -1,14 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Expired")] - Expired {}, -} diff --git a/contracts/cw1155-base/src/execute.rs b/contracts/cw1155-base/src/execute.rs deleted file mode 100644 index ab5a56d78..000000000 --- a/contracts/cw1155-base/src/execute.rs +++ /dev/null @@ -1,312 +0,0 @@ -use cosmwasm_std::{Addr, Binary, DepsMut, Response, StdResult, SubMsg, Uint128}; -use cw1155::{ApproveAllEvent, Cw1155BatchReceiveMsg, Cw1155ReceiveMsg, TokenId, TransferEvent}; -use cw_utils::{Event, Expiration}; - -use crate::{ - contract::ExecuteEnv, - helpers::guard_can_approve, - state::{APPROVES, BALANCES, MINTER, TOKENS}, - ContractError, -}; - -/// When from is None: mint new coins -/// When to is None: burn coins -/// When both are None: no token balance is changed, pointless but valid -/// -/// Make sure permissions are checked before calling this. -fn transfer_inner<'a>( - deps: &'a mut DepsMut, - from: Option<&'a Addr>, - to: Option<&'a Addr>, - token_id: &'a str, - amount: Uint128, -) -> Result, ContractError> { - if let Some(from_addr) = from { - BALANCES.update( - deps.storage, - (from_addr, token_id), - |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_sub(amount)?) - }, - )?; - } - - if let Some(to_addr) = to { - BALANCES.update( - deps.storage, - (to_addr, token_id), - |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_add(amount)?) - }, - )?; - } - - Ok(TransferEvent { - from: from.map(|x| x.as_ref()), - to: to.map(|x| x.as_ref()), - token_id, - amount, - }) -} - -pub fn send_from( - env: ExecuteEnv, - from: String, - to: String, - token_id: TokenId, - amount: Uint128, - msg: Option, -) -> Result { - let from_addr = env.deps.api.addr_validate(&from)?; - let to_addr = env.deps.api.addr_validate(&to)?; - - let ExecuteEnv { - mut deps, - env, - info, - } = env; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - - let event = transfer_inner( - &mut deps, - Some(&from_addr), - Some(&to_addr), - &token_id, - amount, - )?; - event.add_attributes(&mut rsp); - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155ReceiveMsg { - operator: info.sender.to_string(), - from: Some(from), - amount, - token_id: token_id.clone(), - msg, - } - .into_cosmos_msg(to)?, - )] - } - - Ok(rsp) -} - -pub fn mint( - env: ExecuteEnv, - to: String, - token_id: TokenId, - amount: Uint128, - msg: Option, -) -> Result { - let ExecuteEnv { mut deps, info, .. } = env; - - let to_addr = deps.api.addr_validate(&to)?; - - if info.sender != MINTER.load(deps.storage)? { - return Err(ContractError::Unauthorized {}); - } - - let mut rsp = Response::default(); - - let event = transfer_inner(&mut deps, None, Some(&to_addr), &token_id, amount)?; - event.add_attributes(&mut rsp); - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155ReceiveMsg { - operator: info.sender.to_string(), - from: None, - amount, - token_id: token_id.clone(), - msg, - } - .into_cosmos_msg(to)?, - )] - } - - // insert if not exist - if !TOKENS.has(deps.storage, &token_id) { - // we must save some valid data here - TOKENS.save(deps.storage, &token_id, &String::new())?; - } - - Ok(rsp) -} - -pub fn burn( - env: ExecuteEnv, - from: String, - token_id: TokenId, - amount: Uint128, -) -> Result { - let ExecuteEnv { - mut deps, - info, - env, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - - // whoever can transfer these tokens can burn - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - let event = transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; - event.add_attributes(&mut rsp); - Ok(rsp) -} - -pub fn batch_send_from( - env: ExecuteEnv, - from: String, - to: String, - batch: Vec<(TokenId, Uint128)>, - msg: Option, -) -> Result { - let ExecuteEnv { - mut deps, - env, - info, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - let to_addr = deps.api.addr_validate(&to)?; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - for (token_id, amount) in batch.iter() { - let event = transfer_inner( - &mut deps, - Some(&from_addr), - Some(&to_addr), - token_id, - *amount, - )?; - event.add_attributes(&mut rsp); - } - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155BatchReceiveMsg { - operator: info.sender.to_string(), - from: Some(from), - batch, - msg, - } - .into_cosmos_msg(to)?, - )] - }; - - Ok(rsp) -} - -pub fn batch_mint( - env: ExecuteEnv, - to: String, - batch: Vec<(TokenId, Uint128)>, - msg: Option, -) -> Result { - let ExecuteEnv { mut deps, info, .. } = env; - if info.sender != MINTER.load(deps.storage)? { - return Err(ContractError::Unauthorized {}); - } - - let to_addr = deps.api.addr_validate(&to)?; - - let mut rsp = Response::default(); - - for (token_id, amount) in batch.iter() { - let event = transfer_inner(&mut deps, None, Some(&to_addr), token_id, *amount)?; - event.add_attributes(&mut rsp); - - // insert if not exist - if !TOKENS.has(deps.storage, token_id) { - // we must save some valid data here - TOKENS.save(deps.storage, token_id, &String::new())?; - } - } - - if let Some(msg) = msg { - rsp.messages = vec![SubMsg::new( - Cw1155BatchReceiveMsg { - operator: info.sender.to_string(), - from: None, - batch, - msg, - } - .into_cosmos_msg(to)?, - )] - }; - - Ok(rsp) -} - -pub fn batch_burn( - env: ExecuteEnv, - from: String, - batch: Vec<(TokenId, Uint128)>, -) -> Result { - let ExecuteEnv { - mut deps, - info, - env, - } = env; - - let from_addr = deps.api.addr_validate(&from)?; - - guard_can_approve(deps.as_ref(), &env, &from_addr, &info.sender)?; - - let mut rsp = Response::default(); - for (token_id, amount) in batch.into_iter() { - let event = transfer_inner(&mut deps, Some(&from_addr), None, &token_id, amount)?; - event.add_attributes(&mut rsp); - } - Ok(rsp) -} - -pub fn approve_all( - env: ExecuteEnv, - operator: String, - expires: Option, -) -> Result { - let ExecuteEnv { deps, info, env } = env; - - // reject expired data as invalid - let expires = expires.unwrap_or_default(); - if expires.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - - // set the operator for us - let operator_addr = deps.api.addr_validate(&operator)?; - APPROVES.save(deps.storage, (&info.sender, &operator_addr), &expires)?; - - let mut rsp = Response::default(); - ApproveAllEvent { - sender: info.sender.as_ref(), - operator: &operator, - approved: true, - } - .add_attributes(&mut rsp); - Ok(rsp) -} - -pub fn revoke_all(env: ExecuteEnv, operator: String) -> Result { - let ExecuteEnv { deps, info, .. } = env; - let operator_addr = deps.api.addr_validate(&operator)?; - APPROVES.remove(deps.storage, (&info.sender, &operator_addr)); - - let mut rsp = Response::default(); - ApproveAllEvent { - sender: info.sender.as_ref(), - operator: &operator, - approved: false, - } - .add_attributes(&mut rsp); - Ok(rsp) -} diff --git a/contracts/cw1155-base/src/helpers.rs b/contracts/cw1155-base/src/helpers.rs deleted file mode 100644 index 638054f3e..000000000 --- a/contracts/cw1155-base/src/helpers.rs +++ /dev/null @@ -1,30 +0,0 @@ -use cosmwasm_std::{Addr, Deps, Env, StdResult}; - -use crate::{state::APPROVES, ContractError}; - -/// returns true if the sender can execute approve or reject on the contract -pub fn check_can_approve(deps: Deps, env: &Env, owner: &Addr, operator: &Addr) -> StdResult { - // owner can approve - if owner == operator { - return Ok(true); - } - // operator can approve - let op = APPROVES.may_load(deps.storage, (owner, operator))?; - Ok(match op { - Some(ex) => !ex.is_expired(&env.block), - None => false, - }) -} - -pub fn guard_can_approve( - deps: Deps, - env: &Env, - owner: &Addr, - operator: &Addr, -) -> Result<(), ContractError> { - if !check_can_approve(deps, env, owner, operator)? { - Err(ContractError::Unauthorized {}) - } else { - Ok(()) - } -} diff --git a/contracts/cw1155-base/src/lib.rs b/contracts/cw1155-base/src/lib.rs deleted file mode 100644 index 809e67e24..000000000 --- a/contracts/cw1155-base/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -/*! -This is a basic implementation of a cw1155 contract. -It implements the [CW1155 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1155/README.md) and manages multiple tokens -(fungible or non-fungible) under one contract. - -For more information on this contract, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw1155-base/README.md). -*/ - -pub mod contract; -mod error; -pub mod execute; -pub mod helpers; -pub mod msg; -pub mod query; -pub mod state; - -pub use crate::error::ContractError; - -#[cfg(test)] -mod tests; diff --git a/contracts/cw1155-base/src/msg.rs b/contracts/cw1155-base/src/msg.rs deleted file mode 100644 index 07e718d5b..000000000 --- a/contracts/cw1155-base/src/msg.rs +++ /dev/null @@ -1,9 +0,0 @@ -use cosmwasm_schema::cw_serde; - -#[cw_serde] -pub struct InstantiateMsg { - /// The minter is the only one who can create new tokens. - /// This is designed for a base token platform that is controlled by an external program or - /// contract. - pub minter: String, -} diff --git a/contracts/cw1155-base/src/query.rs b/contracts/cw1155-base/src/query.rs deleted file mode 100644 index 0b89b0cba..000000000 --- a/contracts/cw1155-base/src/query.rs +++ /dev/null @@ -1,130 +0,0 @@ -use cosmwasm_std::{Addr, Deps, Env, Order, StdResult}; -use cw1155::{ - ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, IsApprovedForAllResponse, - TokenInfoResponse, TokensResponse, -}; -use cw_storage_plus::Bound; -use cw_utils::{maybe_addr, Expiration}; - -use crate::{ - helpers::check_can_approve, - state::{APPROVES, BALANCES, TOKENS}, -}; - -pub const DEFAULT_LIMIT: u32 = 10; -pub const MAX_LIMIT: u32 = 30; - -pub fn balance(deps: Deps, owner: String, token_id: String) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - - let balance = BALANCES - .may_load(deps.storage, (&owner, &token_id))? - .unwrap_or_default(); - - Ok(BalanceResponse { balance }) -} - -pub fn batch_balance( - deps: Deps, - owner: String, - token_ids: Vec, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - - let balances = token_ids - .into_iter() - .map(|token_id| -> StdResult<_> { - Ok(BALANCES - .may_load(deps.storage, (&owner, &token_id))? - .unwrap_or_default()) - }) - .collect::>()?; - - Ok(BatchBalanceResponse { balances }) -} - -fn build_approval(item: StdResult<(Addr, Expiration)>) -> StdResult { - item.map(|(addr, expires)| cw1155::Approval { - spender: addr.into(), - expires, - }) -} - -pub fn approved_for_all( - deps: Deps, - env: Env, - owner: String, - include_expired: bool, - start_after: Option, - limit: Option, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - let start_after = maybe_addr(deps.api, start_after)?; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.as_ref().map(Bound::exclusive); - - let operators = APPROVES - .prefix(&owner) - .range(deps.storage, start, None, Order::Ascending) - .filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block)) - .take(limit) - .map(build_approval) - .collect::>()?; - - Ok(ApprovedForAllResponse { operators }) -} - -pub fn token_info(deps: Deps, token_id: String) -> StdResult { - let url = TOKENS.load(deps.storage, &token_id)?; - - Ok(TokenInfoResponse { url }) -} - -pub fn is_approved_for_all( - deps: Deps, - env: Env, - owner: String, - operator: String, -) -> StdResult { - let owner_addr = deps.api.addr_validate(&owner)?; - let operator_addr = deps.api.addr_validate(&operator)?; - - let approved = check_can_approve(deps, &env, &owner_addr, &operator_addr)?; - - Ok(IsApprovedForAllResponse { approved }) -} - -pub fn tokens( - deps: Deps, - owner: String, - start_after: Option, - limit: Option, -) -> StdResult { - let owner = deps.api.addr_validate(&owner)?; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.as_ref().map(|s| Bound::exclusive(s.as_str())); - - let tokens = BALANCES - .prefix(&owner) - .keys(deps.storage, start, None, Order::Ascending) - .take(limit) - .collect::>()?; - - Ok(TokensResponse { tokens }) -} - -pub fn all_tokens( - deps: Deps, - start_after: Option, - limit: Option, -) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - 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) - .collect::>()?; - - Ok(TokensResponse { tokens }) -} diff --git a/contracts/cw1155-base/src/state.rs b/contracts/cw1155-base/src/state.rs deleted file mode 100644 index 1238f5094..000000000 --- a/contracts/cw1155-base/src/state.rs +++ /dev/null @@ -1,13 +0,0 @@ -use cosmwasm_std::{Addr, Uint128}; -use cw1155::Expiration; -use cw_storage_plus::{Item, Map}; - -/// Store the minter address who have permission to mint new tokens. -pub const MINTER: Item = Item::new("minter"); -/// Store the balance map, `(owner, token_id) -> balance` -pub const BALANCES: Map<(&Addr, &str), Uint128> = Map::new("balances"); -/// Store the approval status, `(owner, spender) -> expiration` -pub const APPROVES: Map<(&Addr, &Addr), Expiration> = Map::new("approves"); -/// Store the tokens metadata url, also supports enumerating tokens, -/// An entry for token_id must exist as long as there's tokens in circulation. -pub const TOKENS: Map<&str, String> = Map::new("tokens"); diff --git a/contracts/cw1155-base/src/tests.rs b/contracts/cw1155-base/src/tests.rs deleted file mode 100644 index 6202bdef8..000000000 --- a/contracts/cw1155-base/src/tests.rs +++ /dev/null @@ -1,694 +0,0 @@ -use crate::{ - contract::{execute, instantiate, query}, - msg::InstantiateMsg, - ContractError, -}; -use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - to_binary, Binary, OverflowError, Response, StdError, -}; -use cw1155::{ - ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, Cw1155BatchReceiveMsg, - Cw1155ExecuteMsg, Cw1155QueryMsg, Cw1155ReceiveMsg, IsApprovedForAllResponse, - TokenInfoResponse, TokensResponse, -}; -use cw_utils::Expiration; - -#[test] -fn check_transfers() { - // A long test case that try to cover as many cases as possible. - // Summary of what it does: - // - try mint without permission, fail - // - mint with permission, success - // - query balance of receipant, success - // - try transfer without approval, fail - // - approve - // - transfer again, success - // - query balance of transfer participants - // - batch mint token2 and token3, success - // - try batch transfer without approval, fail - // - approve and try batch transfer again, success - // - batch query balances - // - user1 revoke approval to minter - // - query approval status - // - minter try to transfer, fail - // - user1 burn token1 - // - user1 batch burn token2 and token3 - let token1 = "token1".to_owned(); - let token2 = "token2".to_owned(); - let token3 = "token3".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let user2 = String::from("user2"); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // invalid mint, user1 don't mint permission - let mint_msg = Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }; - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - mint_msg.clone(), - ), - Err(ContractError::Unauthorized {}) - )); - - // valid mint - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - mint_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user1) - ); - - // query balance - assert_eq!( - to_binary(&BalanceResponse { - balance: 1u64.into() - }), - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user1.clone(), - token_id: token1.clone(), - } - ), - ); - - let transfer_msg = Cw1155ExecuteMsg::SendFrom { - from: user1.clone(), - to: user2.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }; - - // not approved yet - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - transfer_msg.clone(), - ), - Err(ContractError::Unauthorized {}) - )); - - // approve - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: minter.clone(), - expires: None, - }, - ) - .unwrap(); - - // transfer - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - transfer_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("to", &user2) - ); - - // query balance - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user2.clone(), - token_id: token1.clone(), - } - ), - to_binary(&BalanceResponse { - balance: 1u64.into() - }), - ); - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Balance { - owner: user1.clone(), - token_id: token1.clone(), - } - ), - to_binary(&BalanceResponse { - balance: 0u64.into() - }), - ); - - // batch mint token2 and token3 - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::BatchMint { - to: user2.clone(), - batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())], - msg: None - }, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user2) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &user2) - ); - - // invalid batch transfer, (user2 not approved yet) - let batch_transfer_msg = Cw1155ExecuteMsg::BatchSendFrom { - from: user2.clone(), - to: user1.clone(), - batch: vec![ - (token1.clone(), 1u64.into()), - (token2.clone(), 1u64.into()), - (token3.clone(), 1u64.into()), - ], - msg: None, - }; - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - batch_transfer_msg.clone(), - ), - Err(ContractError::Unauthorized {}), - )); - - // user2 approve - execute( - deps.as_mut(), - mock_env(), - mock_info(user2.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: minter.clone(), - expires: None, - }, - ) - .unwrap(); - - // valid batch transfer - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - batch_transfer_msg, - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user2) - .add_attribute("to", &user1) - ); - - // batch query - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::BatchBalance { - owner: user1.clone(), - token_ids: vec![token1.clone(), token2.clone(), token3.clone()], - } - ), - to_binary(&BatchBalanceResponse { - balances: vec![1u64.into(), 1u64.into(), 1u64.into()] - }), - ); - - // user1 revoke approval - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::RevokeAll { - operator: minter.clone(), - }, - ) - .unwrap(); - - // query approval status - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::IsApprovedForAll { - owner: user1.clone(), - operator: minter.clone(), - } - ), - to_binary(&IsApprovedForAllResponse { approved: false }), - ); - - // tranfer without approval - assert!(matches!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::SendFrom { - from: user1.clone(), - to: user2, - token_id: token1.clone(), - value: 1u64.into(), - msg: None, - }, - ), - Err(ContractError::Unauthorized {}) - )); - - // burn token1 - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::Burn { - from: user1.clone(), - token_id: token1.clone(), - value: 1u64.into(), - } - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - ); - - // burn them all - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::BatchBurn { - from: user1.clone(), - batch: vec![(token2.clone(), 1u64.into()), (token3.clone(), 1u64.into())] - } - ) - .unwrap(), - Response::new() - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token3) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - ); -} - -#[test] -fn check_send_contract() { - let receiver = String::from("receive_contract"); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let token1 = "token1".to_owned(); - let token2 = "token2".to_owned(); - let dummy_msg = Binary::default(); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token2.clone(), - value: 1u64.into(), - msg: None, - }, - ) - .unwrap(); - - // mint to contract - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: receiver.clone(), - token_id: token1.clone(), - value: 1u64.into(), - msg: Some(dummy_msg.clone()), - }, - ) - .unwrap(), - Response::new() - .add_message( - Cw1155ReceiveMsg { - operator: minter.clone(), - from: None, - amount: 1u64.into(), - token_id: token1.clone(), - msg: dummy_msg.clone(), - } - .into_cosmos_msg(receiver.clone()) - .unwrap() - ) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token1) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("to", &receiver) - ); - - // BatchSendFrom - assert_eq!( - execute( - deps.as_mut(), - mock_env(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::BatchSendFrom { - from: user1.clone(), - to: receiver.clone(), - batch: vec![(token2.clone(), 1u64.into())], - msg: Some(dummy_msg.clone()), - }, - ) - .unwrap(), - Response::new() - .add_message( - Cw1155BatchReceiveMsg { - operator: user1.clone(), - from: Some(user1.clone()), - batch: vec![(token2.clone(), 1u64.into())], - msg: dummy_msg, - } - .into_cosmos_msg(receiver.clone()) - .unwrap() - ) - .add_attribute("action", "transfer") - .add_attribute("token_id", &token2) - .add_attribute("amount", 1u64.to_string()) - .add_attribute("from", &user1) - .add_attribute("to", &receiver) - ); -} - -#[test] -fn check_queries() { - // mint multiple types of tokens, and query them - // grant approval to multiple operators, and query them - let tokens = (0..10).map(|i| format!("token{}", i)).collect::>(); - let users = (0..10).map(|i| format!("user{}", i)).collect::>(); - let minter = String::from("minter"); - - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), mock_env(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - mock_env(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::BatchMint { - to: users[0].clone(), - batch: tokens - .iter() - .map(|token_id| (token_id.clone(), 1u64.into())) - .collect::>(), - msg: None, - }, - ) - .unwrap(); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Tokens { - owner: users[0].clone(), - start_after: None, - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[..5].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::Tokens { - owner: users[0].clone(), - start_after: Some("token5".to_owned()), - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[6..].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::AllTokens { - start_after: Some("token5".to_owned()), - limit: Some(5), - }, - ), - to_binary(&TokensResponse { - tokens: tokens[6..].to_owned() - }) - ); - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::TokenInfo { - token_id: "token5".to_owned() - }, - ), - to_binary(&TokenInfoResponse { url: "".to_owned() }) - ); - - for user in users[1..].iter() { - execute( - deps.as_mut(), - mock_env(), - mock_info(users[0].as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user.clone(), - expires: None, - }, - ) - .unwrap(); - } - - assert_eq!( - query( - deps.as_ref(), - mock_env(), - Cw1155QueryMsg::ApprovedForAll { - owner: users[0].clone(), - include_expired: None, - start_after: Some(String::from("user2")), - limit: Some(1), - }, - ), - to_binary(&ApprovedForAllResponse { - operators: vec![cw1155::Approval { - spender: users[3].clone(), - expires: Expiration::Never {} - }], - }) - ); -} - -#[test] -fn approval_expires() { - let mut deps = mock_dependencies(); - let token1 = "token1".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - let user2 = String::from("user2"); - - let env = { - let mut env = mock_env(); - env.block.height = 10; - env - }; - - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - env.clone(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1, - value: 1u64.into(), - msg: None, - }, - ) - .unwrap(); - - // invalid expires should be rejected - assert!(matches!( - execute( - deps.as_mut(), - env.clone(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user2.clone(), - expires: Some(Expiration::AtHeight(5)), - }, - ), - Err(_) - )); - - execute( - deps.as_mut(), - env.clone(), - mock_info(user1.as_ref(), &[]), - Cw1155ExecuteMsg::ApproveAll { - operator: user2.clone(), - expires: Some(Expiration::AtHeight(100)), - }, - ) - .unwrap(); - - let query_msg = Cw1155QueryMsg::IsApprovedForAll { - owner: user1, - operator: user2, - }; - assert_eq!( - query(deps.as_ref(), env, query_msg.clone()), - to_binary(&IsApprovedForAllResponse { approved: true }) - ); - - let env = { - let mut env = mock_env(); - env.block.height = 100; - env - }; - - assert_eq!( - query(deps.as_ref(), env, query_msg,), - to_binary(&IsApprovedForAllResponse { approved: false }) - ); -} - -#[test] -fn mint_overflow() { - let mut deps = mock_dependencies(); - let token1 = "token1".to_owned(); - let minter = String::from("minter"); - let user1 = String::from("user1"); - - let env = mock_env(); - let msg = InstantiateMsg { - minter: minter.clone(), - }; - let res = instantiate(deps.as_mut(), env.clone(), mock_info("operator", &[]), msg).unwrap(); - assert_eq!(0, res.messages.len()); - - execute( - deps.as_mut(), - env.clone(), - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1.clone(), - token_id: token1.clone(), - value: u128::MAX.into(), - msg: None, - }, - ) - .unwrap(); - - assert!(matches!( - execute( - deps.as_mut(), - env, - mock_info(minter.as_ref(), &[]), - Cw1155ExecuteMsg::Mint { - to: user1, - token_id: token1, - value: 1u64.into(), - msg: None, - }, - ), - Err(ContractError::Std(StdError::Overflow { - source: OverflowError { .. }, - .. - })) - )); -} diff --git a/packages/cw1155/.cargo/config b/packages/cw1155/.cargo/config deleted file mode 100644 index 628e18e5b..000000000 --- a/packages/cw1155/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -wasm-debug = "build --lib --target wasm32-unknown-unknown" -schema = "run --bin schema" diff --git a/packages/cw1155/Cargo.toml b/packages/cw1155/Cargo.toml deleted file mode 100644 index 784b5f4c9..000000000 --- a/packages/cw1155/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "cw1155" -version = "0.16.0" -authors = ["Huang Yi "] -edition = "2018" -description = "Definition and types for the CosmWasm-1155 interface" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -[dependencies] -cw-utils = "0.16.0" -cosmwasm-schema = "1.1.0" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/cw1155/README.md b/packages/cw1155/README.md deleted file mode 100644 index a37785ca6..000000000 --- a/packages/cw1155/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# CW1155 Spec: Multiple Tokens - -CW1155 is a specification for managing multiple tokens based on CosmWasm. -The name and design is based on Ethereum's ERC1155 standard. - -The specification is split into multiple sections, a contract may only -implement some of this functionality, but must implement the base. - -Fungible tokens and non-fungible tokens are treated equally, non-fungible tokens just have one max supply. - -Approval is set or unset to some operator over entire set of tokens. (More nuanced control is defined in -[ERC1761](https://eips.ethereum.org/EIPS/eip-1761)) - -## Base - -### Messages - -`SendFrom{from, to, token_id, value, msg}` - This transfers some amount of tokens between two accounts. If `to` is an -address controlled by a smart contract, it must implement the `CW1155Receiver` interface, `msg` will be passed to it -along with other fields, otherwise, `msg` should be `None`. The operator should either be the `from` account or have -approval from it. - -`BatchSendFrom{from, to, batch: Vec<(token_id, value)>, msg}` - Batched version of `SendFrom` which can handle multiple -types of tokens at once. - -`Mint {to, token_id, value, msg}` - This mints some tokens to `to` account, If `to` is controlled by a smart contract, -it should implement `CW1155Receiver` interface, `msg` will be passed to it along with other fields, otherwise, `msg` -should be `None`. - -`BatchMint {to, batch: Vec<(token_id, value)>, msg}` - Batched version of `Mint`. - -`Burn {from, token_id, value}` - This burns some tokens from `from` account. - -`BatchBurn {from, batch: Vec<(token_id, value)>}` - Batched version of `Burn`. - -`ApproveAll{ operator, expires }` - Allows operator to transfer / send any token from the owner's account. If expiration -is set, then this allowance has a time/height limit. - -`RevokeAll { operator }` - Remove previously granted ApproveAll permission - -### Queries - -`Balance { owner, token_id }` - Query the balance of `owner` on particular type of token, default to `0` when record not -exist. - -`BatchBalance { owner, token_ids }` - Query the balance of `owner` on multiple types of tokens, batched version of -`Balance`. - -`ApprovedForAll{owner, include_expired, start_after, limit}` - List all operators that can access all of the owner's -tokens. Return type is `ApprovedForAllResponse`. If `include_expired` is set, show expired owners in the results, -otherwise, ignore them. - -`IsApprovedForAll{owner, operator}` - Query approved status `owner` granted to `operator`. Return type is -`IsApprovedForAllResponse`. - -### Receiver - -Any contract wish to receive CW1155 tokens must implement `Cw1155ReceiveMsg` and `Cw1155BatchReceiveMsg`. - -`Cw1155ReceiveMsg { operator, from, token_id, amount, msg}` - - -`Cw1155BatchReceiveMsg { operator, from, batch, msg}` - - -### Events - -- `transfer(from, to, token_id, value)` - - `from`/`to` are optional, no `from` attribute means minting, no `to` attribute means burning, but they mustn't be -neglected at the same time. - - -## Metadata - -### Queries - -`TokenInfo{ token_id }` - Query metadata url of `token_id`. - -### Events - -`token_info(url, token_id)` - -Metadata url of `token_id` is changed, `url` should point to a json file. - -## Enumerable - -### Queries - -Pagination is acheived via `start_after` and `limit`. Limit is a request -set by the client, if unset, the contract will automatically set it to -`DefaultLimit` (suggested 10). If set, it will be used up to a `MaxLimit` -value (suggested 30). Contracts can define other `DefaultLimit` and `MaxLimit` -values without violating the CW1155 spec, and clients should not rely on -any particular values. - -If `start_after` is unset, the query returns the first results, ordered by -lexogaphically by `token_id`. If `start_after` is set, then it returns the -first `limit` tokens *after* the given one. This allows straight-forward -pagination by taking the last result returned (a `token_id`) and using it -as the `start_after` value in a future query. - -`Tokens{owner, start_after, limit}` - List all token_ids that belong to a given owner. -Return type is `TokensResponse{tokens: Vec}`. - -`AllTokens{start_after, limit}` - Requires pagination. Lists all token_ids controlled by the contract. diff --git a/packages/cw1155/src/bin/schema.rs b/packages/cw1155/src/bin/schema.rs deleted file mode 100644 index 6fe55cb08..000000000 --- a/packages/cw1155/src/bin/schema.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(cw1155::Cw1155ExecuteMsg), &out_dir); - export_schema(&schema_for!(cw1155::Cw1155QueryMsg), &out_dir); - export_schema(&schema_for!(cw1155::Cw1155ReceiveMsg), &out_dir); - export_schema(&schema_for!(cw1155::Cw1155BatchReceiveMsg), &out_dir); - export_schema(&schema_for!(cw1155::BalanceResponse), &out_dir); - export_schema(&schema_for!(cw1155::BatchBalanceResponse), &out_dir); - export_schema(&schema_for!(cw1155::ApprovedForAllResponse), &out_dir); - export_schema(&schema_for!(cw1155::IsApprovedForAllResponse), &out_dir); - export_schema(&schema_for!(cw1155::TokenInfoResponse), &out_dir); - export_schema(&schema_for!(cw1155::TokensResponse), &out_dir); -} diff --git a/packages/cw1155/src/event.rs b/packages/cw1155/src/event.rs deleted file mode 100644 index 2d7709fa8..000000000 --- a/packages/cw1155/src/event.rs +++ /dev/null @@ -1,56 +0,0 @@ -use cosmwasm_std::{attr, Response, Uint128}; -use cw_utils::Event; - -/// Tracks token transfer/mint/burn actions -pub struct TransferEvent<'a> { - pub from: Option<&'a str>, - pub to: Option<&'a str>, - pub token_id: &'a str, - pub amount: Uint128, -} - -impl<'a> Event for TransferEvent<'a> { - fn add_attributes(&self, rsp: &mut Response) { - rsp.attributes.push(attr("action", "transfer")); - rsp.attributes.push(attr("token_id", self.token_id)); - rsp.attributes.push(attr("amount", self.amount)); - if let Some(from) = self.from { - rsp.attributes.push(attr("from", from.to_string())); - } - if let Some(to) = self.to { - rsp.attributes.push(attr("to", to.to_string())); - } - } -} - -/// Tracks token metadata changes -pub struct MetadataEvent<'a> { - pub url: &'a str, - pub token_id: &'a str, -} - -impl<'a> Event for MetadataEvent<'a> { - fn add_attributes(&self, rsp: &mut Response) { - rsp.attributes.push(attr("action", "set_metadata")); - rsp.attributes.push(attr("url", self.url)); - rsp.attributes.push(attr("token_id", self.token_id)); - } -} - -/// Tracks approve_all status changes -pub struct ApproveAllEvent<'a> { - pub sender: &'a str, - pub operator: &'a str, - pub approved: bool, -} - -impl<'a> Event for ApproveAllEvent<'a> { - fn add_attributes(&self, rsp: &mut Response) { - rsp.attributes.push(attr("action", "approve_all")); - rsp.attributes.push(attr("sender", self.sender.to_string())); - rsp.attributes - .push(attr("operator", self.operator.to_string())); - rsp.attributes - .push(attr("approved", (self.approved as u32).to_string())); - } -} diff --git a/packages/cw1155/src/lib.rs b/packages/cw1155/src/lib.rs deleted file mode 100644 index 69bfc5f77..000000000 --- a/packages/cw1155/src/lib.rs +++ /dev/null @@ -1,30 +0,0 @@ -/*! -CW1155 is a specification for managing multiple tokens based on CosmWasm. -The name and design is based on Ethereum's ERC1155 standard. - -The specification is split into multiple sections, a contract may only -implement some of this functionality, but must implement the base. - -Fungible tokens and non-fungible tokens are treated equally, non-fungible tokens just have one max supply. - -Approval is set or unset to some operator over entire set of tokens. (More nuanced control is defined in -[ERC1761](https://eips.ethereum.org/EIPS/eip-1761)) - -For more information on this specification, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw1155/README.md). -*/ - -pub use cw_utils::Expiration; - -pub use crate::event::{ApproveAllEvent, MetadataEvent, TransferEvent}; -pub use crate::msg::{Cw1155ExecuteMsg, TokenId}; -pub use crate::query::{ - Approval, ApprovedForAllResponse, BalanceResponse, BatchBalanceResponse, Cw1155QueryMsg, - IsApprovedForAllResponse, TokenInfoResponse, TokensResponse, -}; -pub use crate::receiver::{Cw1155BatchReceiveMsg, Cw1155ReceiveMsg}; - -mod event; -mod msg; -mod query; -mod receiver; diff --git a/packages/cw1155/src/msg.rs b/packages/cw1155/src/msg.rs deleted file mode 100644 index e8ddce34b..000000000 --- a/packages/cw1155/src/msg.rs +++ /dev/null @@ -1,67 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Binary, Uint128}; -use cw_utils::Expiration; - -pub type TokenId = String; - -#[cw_serde] - -pub enum Cw1155ExecuteMsg { - /// SendFrom is a base message to move tokens, - /// if `env.sender` is the owner or has sufficient pre-approval. - SendFrom { - from: String, - /// If `to` is not contract, `msg` should be `None` - to: String, - token_id: TokenId, - value: Uint128, - /// `None` means don't call the receiver interface - msg: Option, - }, - /// BatchSendFrom is a base message to move multiple types of tokens in batch, - /// if `env.sender` is the owner or has sufficient pre-approval. - BatchSendFrom { - from: String, - /// if `to` is not contract, `msg` should be `None` - to: String, - batch: Vec<(TokenId, Uint128)>, - /// `None` means don't call the receiver interface - msg: Option, - }, - /// Mint is a base message to mint tokens. - Mint { - /// If `to` is not contract, `msg` should be `None` - to: String, - token_id: TokenId, - value: Uint128, - /// `None` means don't call the receiver interface - msg: Option, - }, - /// BatchMint is a base message to mint multiple types of tokens in batch. - BatchMint { - /// If `to` is not contract, `msg` should be `None` - to: String, - batch: Vec<(TokenId, Uint128)>, - /// `None` means don't call the receiver interface - msg: Option, - }, - /// Burn is a base message to burn tokens. - Burn { - from: String, - token_id: TokenId, - value: Uint128, - }, - /// BatchBurn is a base message to burn multiple types of tokens in batch. - BatchBurn { - from: String, - batch: Vec<(TokenId, Uint128)>, - }, - /// Allows operator to transfer / send any token from the owner's account. - /// If expiration is set, then this allowance has a time/height limit - ApproveAll { - operator: String, - expires: Option, - }, - /// Remove previously granted ApproveAll permission - RevokeAll { operator: String }, -} diff --git a/packages/cw1155/src/query.rs b/packages/cw1155/src/query.rs deleted file mode 100644 index b20076911..000000000 --- a/packages/cw1155/src/query.rs +++ /dev/null @@ -1,94 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Uint128; -use cw_utils::Expiration; - -use crate::msg::TokenId; - -#[cw_serde] -#[derive(QueryResponses)] -pub enum Cw1155QueryMsg { - /// Returns the current balance of the given address, 0 if unset. - #[returns(BalanceResponse)] - Balance { owner: String, token_id: TokenId }, - /// Returns the current balance of the given address for a batch of tokens, 0 if unset. - #[returns(BatchBalanceResponse)] - BatchBalance { - owner: String, - token_ids: Vec, - }, - /// List all operators that can access all of the owner's tokens. - #[returns(ApprovedForAllResponse)] - ApprovedForAll { - owner: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - start_after: Option, - limit: Option, - }, - /// Query approved status `owner` granted to `operator`. - #[returns(IsApprovedForAllResponse)] - IsApprovedForAll { owner: String, operator: String }, - - /// With MetaData Extension. - /// Query metadata of token - #[returns(TokenInfoResponse)] - TokenInfo { token_id: TokenId }, - - /// With Enumerable extension. - /// Returns all tokens owned by the given address, [] if unset. - #[returns(TokensResponse)] - Tokens { - owner: String, - start_after: Option, - limit: Option, - }, - /// With Enumerable extension. - /// Requires pagination. Lists all token_ids controlled by the contract. - #[returns(TokensResponse)] - AllTokens { - start_after: Option, - limit: Option, - }, -} - -#[cw_serde] -pub struct BalanceResponse { - pub balance: Uint128, -} - -#[cw_serde] -pub struct BatchBalanceResponse { - pub balances: Vec, -} - -#[cw_serde] -pub struct Approval { - /// Account that can transfer/send the token - pub spender: String, - /// When the Approval expires (maybe Expiration::never) - pub expires: Expiration, -} - -#[cw_serde] -pub struct ApprovedForAllResponse { - pub operators: Vec, -} - -#[cw_serde] -pub struct IsApprovedForAllResponse { - pub approved: bool, -} - -#[cw_serde] -pub struct TokenInfoResponse { - /// Should be a url point to a json file - pub url: String, -} - -#[cw_serde] -pub struct TokensResponse { - /// Contains all token_ids in lexicographical ordering - /// If there are more than `limit`, use `start_from` in future queries - /// to achieve pagination. - pub tokens: Vec, -} diff --git a/packages/cw1155/src/receiver.rs b/packages/cw1155/src/receiver.rs deleted file mode 100644 index c56dab43a..000000000 --- a/packages/cw1155/src/receiver.rs +++ /dev/null @@ -1,73 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; - -use crate::msg::TokenId; - -/// Cw1155ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg -#[cw_serde] - -pub struct Cw1155ReceiveMsg { - /// The account that executed the send message - pub operator: String, - /// The account that the token transfered from - pub from: Option, - pub token_id: TokenId, - pub amount: Uint128, - pub msg: Binary, -} - -impl Cw1155ReceiveMsg { - /// serializes the message - pub fn into_binary(self) -> StdResult { - let msg = ReceiverExecuteMsg::Receive(self); - to_binary(&msg) - } - - /// creates a cosmos_msg sending this struct to the named contract - pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; - let execute = WasmMsg::Execute { - contract_addr: contract_addr.into(), - msg, - funds: vec![], - }; - Ok(execute.into()) - } -} - -/// Cw1155BatchReceiveMsg should be de/serialized under `BatchReceive()` variant in a ExecuteMsg -#[cw_serde] - -pub struct Cw1155BatchReceiveMsg { - pub operator: String, - pub from: Option, - pub batch: Vec<(TokenId, Uint128)>, - pub msg: Binary, -} - -impl Cw1155BatchReceiveMsg { - /// serializes the message - pub fn into_binary(self) -> StdResult { - let msg = ReceiverExecuteMsg::BatchReceive(self); - to_binary(&msg) - } - - /// creates a cosmos_msg sending this struct to the named contract - pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; - let execute = WasmMsg::Execute { - contract_addr: contract_addr.into(), - msg, - funds: vec![], - }; - Ok(execute.into()) - } -} - -// This is just a helper to properly serialize the above message -#[cw_serde] - -enum ReceiverExecuteMsg { - Receive(Cw1155ReceiveMsg), - BatchReceive(Cw1155BatchReceiveMsg), -} From 350961a101f40dcf56feb76c2f8737c21482037c Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 18 Oct 2022 22:29:21 +0200 Subject: [PATCH 541/631] align CI --- .circleci/config.yml | 149 ------------------------------------------- 1 file changed, 149 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1bd7f83a6..aa1cc07b6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,28 +15,14 @@ workflows: - contract_cw4_stake - contract_cw20_base - contract_cw20_ics20 - - contract_cw1155_base - package_controllers - - package_utils - package_cw1 - package_cw2 - package_cw3 - package_cw4 - package_cw20 - - package_cw1155 - - package_multi_test - - package_storage_plus - lint - wasm-build - - benchmarking: - requires: - - package_storage_plus - filters: - branches: - only: - # Long living branches - - main - # 👇Add your branch here if benchmarking matters to your work - coverage deploy: jobs: @@ -270,33 +256,6 @@ jobs: - target key: cargocache-cw20-ics20-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - contract_cw1155_base: - docker: - - image: rust:1.58.1 - working_directory: ~/project/contracts/cw1155-base - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version - - restore_cache: - keys: - - cargocache-cw1155-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Unit Tests - environment: - RUST_BACKTRACE: 1 - command: cargo unit-test --locked - - run: - name: Build and run schema generator - command: cargo schema --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-cw1155-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - package_controllers: docker: - image: rust:1.58.1 @@ -322,31 +281,6 @@ jobs: - target key: cargocache-v2-controllers:1.58.1-{{ checksum "~/project/Cargo.lock" }} - package_utils: - docker: - - image: rust:1.58.1 - working_directory: ~/project/packages/utils - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version; rustup target list --installed - - restore_cache: - keys: - - cargocache-v2-utils:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Build library for native target - command: cargo build --locked - - run: - name: Run unit tests - command: cargo test --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-utils:1.58.1-{{ checksum "~/project/Cargo.lock" }} - package_cw1: docker: - image: rust:1.58.1 @@ -584,89 +518,6 @@ jobs: name: Check wasm contracts command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm - package_multi_test: - docker: - - image: rust:1.58.1 - working_directory: ~/project/packages/multi-test - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version; rustup target list --installed - - restore_cache: - keys: - - cargocache-v2-multi-test:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Build library for native target - command: cargo build --locked - - run: - name: Run unit tests - command: cargo test --locked - - run: - name: Run unit tests (with iterator) - command: cargo test --locked --features iterator - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-multi-test:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - package_storage_plus: - docker: - - image: rust:1.58.1 - working_directory: ~/project/packages/storage-plus - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version; rustup target list --installed - - restore_cache: - keys: - - 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 - - run: - name: Run unit tests (no iterator) - command: cargo test --locked --no-default-features - - run: - name: Build library for native target (with iterator and macro) - command: cargo build --locked --all-features - - run: - name: Run unit tests (with iterator and macro) - command: cargo test --locked --all-features - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-storage-plus:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - benchmarking: - docker: - - image: rust:1.58.1 - environment: - RUST_BACKTRACE: 1 - steps: - - checkout: - path: ~/project - - run: - name: Version information (default; stable) - command: rustc --version && cargo --version - - restore_cache: - keys: - - cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Run storage-plus benchmarks - working_directory: ~/project/packages/storage-plus - command: cargo bench -- --color never --save-baseline - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-benchmarking-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} - coverage: # https://circleci.com/developer/images?imageType=machine machine: From 0ceab105974bc4e9fac75feb1bcbfaa201878a6a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 18 Oct 2022 22:54:52 +0200 Subject: [PATCH 542/631] Align publish.sh --- scripts/publish.sh | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 27028ac21..3a210db91 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -13,34 +13,19 @@ then exit 1 fi -# this should really more to cosmwasm... -STORAGE_PACKAGES="storage-macro storage-plus" # these are imported by other packages BASE_PACKAGES="cw2" -UTILS_PACKAGES="utils" -ALL_PACKAGES="controllers cw1 cw3 cw4 cw20 cw1155 multi-test" +ALL_PACKAGES="controllers cw1 cw3 cw4 cw20" # This is imported by cw3-fixed-multisig, which is imported by cw3-flex-multisig # need to make a separate category to remove race conditions CW20_BASE="cw20-base" # these are imported by other contracts BASE_CONTRACTS="cw1-whitelist cw4-group cw3-fixed-multisig " -ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-ics20 cw1155-base" +ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-ics20" SLEEP_TIME=30 -for pack in $STORAGE_PACKAGES; do - ( - cd "packages/$pack" - echo "Publishing $pack" - cargo publish - ) -done - -# wait for these to be processed on crates.io -echo "Waiting for publishing storage packages" -sleep $SLEEP_TIME - for pack in $BASE_PACKAGES; do ( cd "packages/$pack" @@ -53,18 +38,6 @@ done echo "Waiting for publishing base packages" sleep $SLEEP_TIME -for pack in $UTILS_PACKAGES; do - ( - cd "packages/$pack" - echo "Publishing $pack" - cargo publish - ) -done - -# wait for these to be processed on crates.io -echo "Waiting for publishing utils packages" -sleep $SLEEP_TIME - for pack in $ALL_PACKAGES; do ( cd "packages/$pack" From 7bd106c26a024c060ab81924211fd00fed580a20 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 19 Oct 2022 12:44:18 +0200 Subject: [PATCH 543/631] Remove the AGPL license --- LICENSE-APACHE => LICENSE | 0 LICENSE-AGPL.md | 660 ---------------------------- NOTICE | 15 +- README.md | 9 +- contracts/cw1-subkeys/NOTICE | 14 - contracts/cw1-whitelist/NOTICE | 14 - contracts/cw20-base/NOTICE | 14 - contracts/cw20-ics20/NOTICE | 14 - contracts/cw3-fixed-multisig/NOTICE | 14 - contracts/cw3-flex-multisig/NOTICE | 14 - contracts/cw4-group/NOTICE | 14 - contracts/cw4-stake/NOTICE | 14 - packages/controllers/NOTICE | 14 - packages/cw1/NOTICE | 14 - packages/cw2/NOTICE | 14 - packages/cw20/NOTICE | 14 - packages/cw3/NOTICE | 14 - packages/cw4/NOTICE | 14 - 18 files changed, 14 insertions(+), 866 deletions(-) rename LICENSE-APACHE => LICENSE (100%) delete mode 100644 LICENSE-AGPL.md delete mode 100644 contracts/cw1-subkeys/NOTICE delete mode 100644 contracts/cw1-whitelist/NOTICE delete mode 100644 contracts/cw20-base/NOTICE delete mode 100644 contracts/cw20-ics20/NOTICE delete mode 100644 contracts/cw3-fixed-multisig/NOTICE delete mode 100644 contracts/cw3-flex-multisig/NOTICE delete mode 100644 contracts/cw4-group/NOTICE delete mode 100644 contracts/cw4-stake/NOTICE delete mode 100644 packages/controllers/NOTICE delete mode 100644 packages/cw1/NOTICE delete mode 100644 packages/cw2/NOTICE delete mode 100644 packages/cw20/NOTICE delete mode 100644 packages/cw3/NOTICE delete mode 100644 packages/cw4/NOTICE diff --git a/LICENSE-APACHE b/LICENSE similarity index 100% rename from LICENSE-APACHE rename to LICENSE diff --git a/LICENSE-AGPL.md b/LICENSE-AGPL.md deleted file mode 100644 index e066202aa..000000000 --- a/LICENSE-AGPL.md +++ /dev/null @@ -1,660 +0,0 @@ -### GNU AFFERO GENERAL PUBLIC LICENSE - -Version 3, 19 November 2007 - -Copyright (C) 2007 Free Software Foundation, Inc. - - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - -### Preamble - -The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - -The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains -free software for all its users. - -When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - -Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - -A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - -The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - -An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing -under this license. - -The precise terms and conditions for copying, distribution and -modification follow. - -### TERMS AND CONDITIONS - -#### 0. Definitions. - -"This License" refers to version 3 of the GNU Affero General Public -License. - -"Copyright" also means copyright-like laws that apply to other kinds -of works, such as semiconductor masks. - -"The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - -To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of -an exact copy. The resulting work is called a "modified version" of -the earlier work or a work "based on" the earlier work. - -A "covered work" means either the unmodified Program or a work based -on the Program. - -To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - -To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user -through a computer network, with no transfer of a copy, is not -conveying. - -An interactive user interface displays "Appropriate Legal Notices" to -the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -#### 1. Source Code. - -The "source code" for a work means the preferred form of the work for -making modifications to it. "Object code" means any non-source form of -a work. - -A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - -The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - -The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can -regenerate automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same -work. - -#### 2. Basic Permissions. - -All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, -without conditions so long as your license otherwise remains in force. -You may convey covered works to others for the sole purpose of having -them make modifications exclusively for you, or provide you with -facilities for running those works, provided that you comply with the -terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for -you must do so exclusively on your behalf, under your direction and -control, on terms that prohibit them from making any copies of your -copyrighted material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the -conditions stated below. Sublicensing is not allowed; section 10 makes -it unnecessary. - -#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - -No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - -When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such -circumvention is effected by exercising rights under this License with -respect to the covered work, and you disclaim any intention to limit -operation or modification of the work as a means of enforcing, against -the work's users, your or third parties' legal rights to forbid -circumvention of technological measures. - -#### 4. Conveying Verbatim Copies. - -You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - -#### 5. Conveying Modified Source Versions. - -You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these -conditions: - -- a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. -- b) The work must carry prominent notices stating that it is - released under this License and any conditions added under - section 7. This requirement modifies the requirement in section 4 - to "keep intact all notices". -- c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. -- d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - -A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - -#### 6. Conveying Non-Source Forms. - -You may convey a covered work in object code form under the terms of -sections 4 and 5, provided that you also convey the machine-readable -Corresponding Source under the terms of this License, in one of these -ways: - -- a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. -- b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the Corresponding - Source from a network server at no charge. -- c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. -- d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. -- e) Convey the object code using peer-to-peer transmission, - provided you inform other peers where the object code and - Corresponding Source of the work are being offered to the general - public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - -A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, -family, or household purposes, or (2) anything designed or sold for -incorporation into a dwelling. In determining whether a product is a -consumer product, doubtful cases shall be resolved in favor of -coverage. For a particular product received by a particular user, -"normally used" refers to a typical or common use of that class of -product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected -to use, the product. A product is a consumer product regardless of -whether the product has substantial commercial, industrial or -non-consumer uses, unless such uses represent the only significant -mode of use of the product. - -"Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to -install and execute modified versions of a covered work in that User -Product from a modified version of its Corresponding Source. The -information must suffice to ensure that the continued functioning of -the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - -The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or -updates for a work that has been modified or installed by the -recipient, or for the User Product in which it has been modified or -installed. Access to a network may be denied when the modification -itself materially and adversely affects the operation of the network -or violates the rules and protocols for communication across the -network. - -Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - -#### 7. Additional Terms. - -"Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders -of that material) supplement the terms of this License with terms: - -- a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or -- b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or -- c) Prohibiting misrepresentation of the origin of that material, - or requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or -- d) Limiting the use for publicity purposes of names of licensors - or authors of the material; or -- e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or -- f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions - of it) with contractual assumptions of liability to the recipient, - for any liability that these contractual assumptions directly - impose on those licensors and authors. - -All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; the -above requirements apply either way. - -#### 8. Termination. - -You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - -#### 9. Acceptance Not Required for Having Copies. - -You are not required to accept this License in order to receive or run -a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - -#### 10. Automatic Licensing of Downstream Recipients. - -Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - -An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - -#### 11. Patents. - -A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - -A contributor's "essential patent claims" are all patent claims owned -or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - -In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - -If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - -A patent license is "discriminatory" if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on -the non-exercise of one or more of the rights that are specifically -granted under this License. You may not convey a covered work if you -are a party to an arrangement with a third party that is in the -business of distributing software, under which you make payment to the -third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties -who would receive the covered work from you, a discriminatory patent -license (a) in connection with copies of the covered work conveyed by -you (or copies made from those copies), or (b) primarily for and in -connection with specific products or compilations that contain the -covered work, unless you entered into that arrangement, or that patent -license was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - -#### 12. No Surrender of Others' Freedom. - -If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under -this License and any other pertinent obligations, then as a -consequence you may not convey it at all. For example, if you agree to -terms that obligate you to collect a royalty for further conveying -from those to whom you convey the Program, the only way you could -satisfy both those terms and this License would be to refrain entirely -from conveying the Program. - -#### 13. Remote Network Interaction; Use with the GNU General Public License. - -Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your -version supports such interaction) an opportunity to receive the -Corresponding Source of your version by providing access to the -Corresponding Source from a network server at no charge, through some -standard or customary means of facilitating copying of software. This -Corresponding Source shall include the Corresponding Source for any -work covered by version 3 of the GNU General Public License that is -incorporated pursuant to the following paragraph. - -Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - -#### 14. Revised Versions of this License. - -The Free Software Foundation may publish revised and/or new versions -of the GNU Affero General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever -published by the Free Software Foundation. - -If the Program specifies that a proxy can decide which future versions -of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - -Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - -#### 15. Disclaimer of Warranty. - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - -#### 16. Limitation of Liability. - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR -CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT -NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM -TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER -PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -#### 17. Interpretation of Sections 15 and 16. - -If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - -END OF TERMS AND CONDITIONS - -### How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - -To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively state -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper -mail. - -If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for -the specific requirements. - -You should also get your employer (if you work as a programmer) or -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. For more information on this, and how to apply and follow -the GNU AGPL, see . \ No newline at end of file diff --git a/NOTICE b/NOTICE index 09d5a6ba7..36bad9fd2 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,15 @@ CosmWasm-Plus: A collection of production-quality CosmWasm contracts -Different crates in this repo may be either Apache-2.0 or AGPL-3.0 licensed. -Please refer to the NOTICE file in each crate (and the Cargo.toml metadata) \ No newline at end of file +Copyright 2021 Confio GmbH + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index c097c9aca..9d6a4beda 100644 --- a/README.md +++ b/README.md @@ -206,16 +206,9 @@ auto-detect the latest version tag for you, with --latest-tag. ## Licenses -This repo contains two license, [Apache 2.0](./LICENSE-APACHE) and -[AGPL 3.0](./LICENSE-AGPL.md). All crates in this repo may be licensed -as one or the other. Please check the `NOTICE` in each crate or the -relevant `Cargo.toml` file for clarity. +This repo is licensed under [Apache 2.0](./LICENSE). All *specifications* will always be Apache-2.0. All contracts that are meant to be *building blocks* will also be Apache-2.0. This is along the lines of Open Zeppelin or other public references. -Contracts that are "ready to deploy" may be licensed under AGPL 3.0 to -encourage anyone using them to contribute back any improvements they -make. This is common practice for actual projects running on Ethereum, -like Uniswap or Maker DAO. diff --git a/contracts/cw1-subkeys/NOTICE b/contracts/cw1-subkeys/NOTICE deleted file mode 100644 index 750469d26..000000000 --- a/contracts/cw1-subkeys/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW1-SubKeys: A CosmWasm proxy contract with send allowances -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw1-whitelist/NOTICE b/contracts/cw1-whitelist/NOTICE deleted file mode 100644 index 3002a4406..000000000 --- a/contracts/cw1-whitelist/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW1-Whitelist: A minimal CosmWasm proxy contract -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-base/NOTICE b/contracts/cw20-base/NOTICE deleted file mode 100644 index 84b1c2103..000000000 --- a/contracts/cw20-base/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-Base: A reference implementation for fungible token on CosmWasm -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw20-ics20/NOTICE b/contracts/cw20-ics20/NOTICE deleted file mode 100644 index bc266454e..000000000 --- a/contracts/cw20-ics20/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-ICS20: IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw3-fixed-multisig/NOTICE b/contracts/cw3-fixed-multisig/NOTICE deleted file mode 100644 index e411deead..000000000 --- a/contracts/cw3-fixed-multisig/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW3-Fixed-Whitelist: Minimal voting contract as fixed group multisig -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw3-flex-multisig/NOTICE b/contracts/cw3-flex-multisig/NOTICE deleted file mode 100644 index 8f613f7be..000000000 --- a/contracts/cw3-flex-multisig/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW3-Flex-Whitelist: Implementing cw3 with multiple voting patterns and dynamic groups -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw4-group/NOTICE b/contracts/cw4-group/NOTICE deleted file mode 100644 index d459f5e2e..000000000 --- a/contracts/cw4-group/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Cw4_group -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/cw4-stake/NOTICE b/contracts/cw4-stake/NOTICE deleted file mode 100644 index 4a0722a3c..000000000 --- a/contracts/cw4-stake/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Cw4-Stake: implementation of group based on staked tokens -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/controllers/NOTICE b/packages/controllers/NOTICE deleted file mode 100644 index 816d83eea..000000000 --- a/packages/controllers/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW-Controllers: Common controllers we can reuse in many contracts -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/cw1/NOTICE b/packages/cw1/NOTICE deleted file mode 100644 index 60b98d3d1..000000000 --- a/packages/cw1/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW1: A CosmWasm spec for proxy contracts -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/cw2/NOTICE b/packages/cw2/NOTICE deleted file mode 100644 index 82362cb1e..000000000 --- a/packages/cw2/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW2: A CosmWasm spec for migration info -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/cw20/NOTICE b/packages/cw20/NOTICE deleted file mode 100644 index 8c1b03266..000000000 --- a/packages/cw20/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20: A CosmWasm spec for fungible token contracts -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/cw3/NOTICE b/packages/cw3/NOTICE deleted file mode 100644 index 05eb9c318..000000000 --- a/packages/cw3/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW3: A CosmWasm spec for on-chain multiSig/voting contracts -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/cw4/NOTICE b/packages/cw4/NOTICE deleted file mode 100644 index c22a4f2fc..000000000 --- a/packages/cw4/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW4: A CosmWasm spec for groups -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. From dbb3965f63aa7a45e7729b8295caf90d65b3cf28 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 19 Oct 2022 18:03:39 +0200 Subject: [PATCH 544/631] Add year 2022 to copyright notice --- NOTICE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE b/NOTICE index 36bad9fd2..d33156937 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,6 @@ CosmWasm-Plus: A collection of production-quality CosmWasm contracts -Copyright 2021 Confio GmbH +Copyright 2021,2022 Confio GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 38ef4c210b03a81493181a79e360bf507852ec80 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 19 Oct 2022 19:07:37 +0200 Subject: [PATCH 545/631] Remove old packages from README --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 9d6a4beda..8d3fd6b68 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,10 @@ | cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw1155 | [![cw1155 on crates.io](https://img.shields.io/crates/v/cw1155.svg)](https://crates.io/crates/cw1155) | [![Docs](https://docs.rs/cw1155/badge.svg)](https://docs.rs/cw1155) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | Utilities | Crates.io | Docs | Coverage | |-----------------|----------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| | cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw-multi-test | [![cw-multi-test on crates.io](https://img.shields.io/crates/v/cw-multi-test.svg)](https://crates.io/crates/cw-multi-test) | [![Docs](https://docs.rs/cw-multi-test/badge.svg)](https://docs.rs/cw-multi-test) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | -| cw-storage-plus | [![cw-storage-plus on crates.io](https://img.shields.io/crates/v/cw-storage-plus.svg)](https://crates.io/crates/cw-storage-plus) | [![Docs](https://docs.rs/cw-storage-plus/badge.svg)](https://docs.rs/cw-storage-plus) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw-utils | [![cw-utils on crates.io](https://img.shields.io/crates/v/cw-utils.svg)](https://crates.io/crates/cw-utils) | [![Docs](https://docs.rs/cw-utils/badge.svg)](https://docs.rs/cw-utils) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | - | Contracts | Download | Docs | Coverage | |--------------------|----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| | cw1-subkeys | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | @@ -28,7 +23,6 @@ | cw4-stake | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw4_stake.wasm) | [![Docs](https://docs.rs/cw4-stake/badge.svg)](https://docs.rs/cw4-stake) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20-ics20 | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw1155-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1155_base.wasm) | [![Docs](https://docs.rs/cw1155-base/badge.svg)](https://docs.rs/cw1155-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be followed there. From 5e43177de73d7211ed9d084213c7bb91736158e4 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 19 Oct 2022 21:10:47 +0200 Subject: [PATCH 546/631] CI: bump Rust version --- .circleci/config.yml | 114 +++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index aa1cc07b6..a0c2ec041 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,21 +28,21 @@ workflows: jobs: - build_and_upload_contracts: filters: - tags: - only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ - branches: - ignore: /.*/ + tags: + only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ + branches: + ignore: /.*/ - build_and_upload_schemas: filters: - tags: - only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ - branches: - ignore: /.*/ + tags: + only: /^v[0-9]+\.[0-9]+\.[0-9]+.*/ + branches: + ignore: /.*/ jobs: contract_cw1_subkeys: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw1-subkeys steps: - checkout: @@ -52,7 +52,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-subkeys-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -65,11 +65,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-subkeys-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw1-whitelist steps: - checkout: @@ -79,7 +79,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -92,11 +92,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw3-fixed-multisig steps: - checkout: @@ -106,7 +106,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-fixed-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -119,11 +119,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-fixed-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw3-flex-multisig steps: - checkout: @@ -133,7 +133,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-flex-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -146,11 +146,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-flex-multisig-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw4-group steps: - checkout: @@ -160,7 +160,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-group-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -173,11 +173,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-group-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw4-stake steps: - checkout: @@ -187,7 +187,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-stake-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -200,11 +200,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-stake-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw20-base steps: - checkout: @@ -214,7 +214,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -227,11 +227,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-base-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/contracts/cw20-ics20 steps: - checkout: @@ -241,7 +241,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-ics20-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -254,11 +254,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-ics20-rust:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_controllers: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/controllers steps: - checkout: @@ -268,7 +268,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-controllers:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-controllers:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -279,11 +279,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-controllers:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-controllers:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw1 steps: - checkout: @@ -293,7 +293,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -307,11 +307,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw2: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw2 steps: - checkout: @@ -321,7 +321,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw2:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw2:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -333,11 +333,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw2:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw2:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw3 steps: - checkout: @@ -347,7 +347,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw3:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -361,11 +361,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw3:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw4 steps: - checkout: @@ -375,7 +375,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw4:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -389,11 +389,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw4:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw20 steps: - checkout: @@ -403,7 +403,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw20:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -417,11 +417,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw20:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.64.0-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project/packages/cw1155 steps: - checkout: @@ -431,7 +431,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1155:1.58.1-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -445,11 +445,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1155:1.58.1-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.64.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 steps: - checkout - run: @@ -457,7 +457,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.58.1-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.64.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -476,7 +476,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.58.1-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.64.0-{{ 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 @@ -581,7 +581,7 @@ jobs: build_and_upload_schemas: docker: - - image: rust:1.58.1 + - image: rust:1.64.0 working_directory: ~/project steps: - checkout: From 6c0174b9530fde6e625a62ec7b9b15e82d17a130 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 19 Oct 2022 21:55:20 +0200 Subject: [PATCH 547/631] Update Rust edition across the board --- contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-ics20/Cargo.toml | 2 +- contracts/cw3-fixed-multisig/Cargo.toml | 2 +- contracts/cw3-flex-multisig/Cargo.toml | 2 +- contracts/cw4-group/Cargo.toml | 2 +- contracts/cw4-stake/Cargo.toml | 2 +- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 2 +- packages/cw4/Cargo.toml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index a2ea8749f..658eeb57d 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -2,7 +2,7 @@ name = "cw1-subkeys" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 34dd9d53f..47fb37e6f 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -2,7 +2,7 @@ name = "cw1-whitelist" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implementation of an proxy contract using a whitelist" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index bc1683b4c..10235b426 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -2,7 +2,7 @@ name = "cw20-base" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 9b58330b5..b74d4fd34 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -2,7 +2,7 @@ name = "cw20-ics20" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index f9ab43376..2e9208861 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -2,7 +2,7 @@ name = "cw3-fixed-multisig" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implementing cw3 with an fixed group multisig" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 291f5e51c..076bd6638 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -2,7 +2,7 @@ name = "cw3-flex-multisig" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index dba3b7f54..3f431f4b1 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -2,7 +2,7 @@ name = "cw4-group" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index af8e1f734..0bcdc0c72 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -2,7 +2,7 @@ name = "cw4-stake" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "CW4 implementation of group based on staked tokens" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index e7083ed75..340a9ac4a 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -2,7 +2,7 @@ name = "cw-controllers" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Common controllers we can reuse in many contracts" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 35209202c..8ea1f149a 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -2,7 +2,7 @@ name = "cw1" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Definition and types for the CosmWasm-1 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index feab0a89b..e7f02ed12 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -2,7 +2,7 @@ name = "cw2" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Definition and types for the CosmWasm-2 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index fe912af57..a71df10b1 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -2,7 +2,7 @@ name = "cw20" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Definition and types for the CosmWasm-20 interface" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 4c21b571f..2835d3268 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -2,7 +2,7 @@ name = "cw3" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index adb1ddaed..ac01aea3a 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -2,7 +2,7 @@ name = "cw4" version = "0.16.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "CosmWasm-4 Interface: Groups Members" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" From b2071b742624d44af3aa0bdb0aeb807f65e862a1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 26 Aug 2021 20:09:00 +0200 Subject: [PATCH 548/631] Use QuerierWrapper not Querier in cw20 helpers --- packages/cw20/src/helpers.rs | 103 ++++++++++++++--------------------- 1 file changed, 42 insertions(+), 61 deletions(-) diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index f38ef3386..1b1f2c067 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, Uint128, WasmMsg, - WasmQuery, + to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, Uint128, + WasmMsg, WasmQuery, }; use crate::{ @@ -31,89 +31,70 @@ impl Cw20Contract { .into()) } - /// Get token balance for the given address - pub fn balance(&self, querier: &Q, address: T) -> StdResult - where - Q: Querier, - T: Into, - CQ: CustomQuery, - { - let msg = Cw20QueryMsg::Balance { - address: address.into(), - }; - let query = WasmQuery::Smart { + fn encode_smart_query( + &self, + msg: Cw20QueryMsg, + ) -> StdResult> { + Ok(WasmQuery::Smart { contract_addr: self.addr().into(), msg: to_binary(&msg)?, } - .into(); - let res: BalanceResponse = QuerierWrapper::::new(querier).query(&query)?; + .into()) + } + + /// Get token balance for the given address + pub fn balance, CQ: CustomQuery>( + &self, + querier: &QuerierWrapper, + address: T, + ) -> StdResult { + let query = self.encode_smart_query(Cw20QueryMsg::Balance { + address: address.into(), + })?; + let res: BalanceResponse = querier.query(&query)?; Ok(res.balance) } /// Get metadata from the contract. This is a good check that the address /// is a valid Cw20 contract. - pub fn meta(&self, querier: &Q) -> StdResult - where - Q: Querier, - CQ: CustomQuery, - { - let msg = Cw20QueryMsg::TokenInfo {}; - let query = WasmQuery::Smart { - contract_addr: self.addr().into(), - msg: to_binary(&msg)?, - } - .into(); - QuerierWrapper::::new(querier).query(&query) + pub fn meta( + &self, + querier: &QuerierWrapper, + ) -> StdResult { + let query = self.encode_smart_query(Cw20QueryMsg::TokenInfo {})?; + querier.query(&query) } /// Get allowance of spender to use owner's account - pub fn allowance( + pub fn allowance, U: Into, CQ: CustomQuery>( &self, - querier: &Q, + querier: &QuerierWrapper, owner: T, spender: U, - ) -> StdResult - where - Q: Querier, - T: Into, - U: Into, - CQ: CustomQuery, - { - let msg = Cw20QueryMsg::Allowance { + ) -> StdResult { + let query = self.encode_smart_query(Cw20QueryMsg::Allowance { owner: owner.into(), spender: spender.into(), - }; - let query = WasmQuery::Smart { - contract_addr: self.addr().into(), - msg: to_binary(&msg)?, - } - .into(); - QuerierWrapper::::new(querier).query(&query) + })?; + querier.query(&query) } /// Find info on who can mint, and how much - pub fn minter(&self, querier: &Q) -> StdResult> - where - Q: Querier, - CQ: CustomQuery, - { - let msg = Cw20QueryMsg::Minter {}; - let query = WasmQuery::Smart { - contract_addr: self.addr().into(), - msg: to_binary(&msg)?, - } - .into(); - QuerierWrapper::::new(querier).query(&query) + pub fn minter( + &self, + querier: &QuerierWrapper, + ) -> StdResult> { + let query = self.encode_smart_query(Cw20QueryMsg::Minter {})?; + querier.query(&query) } /// returns true if the contract supports the allowance extension - pub fn has_allowance(&self, querier: &Q) -> bool { - self.allowance::<_, _, _, CQ>(querier, self.addr(), self.addr()) - .is_ok() + pub fn has_allowance(&self, querier: &QuerierWrapper) -> bool { + self.allowance(querier, self.addr(), self.addr()).is_ok() } /// returns true if the contract supports the mintable extension - pub fn is_mintable(&self, querier: &Q) -> bool { - self.minter::<_, CQ>(querier).is_ok() + pub fn is_mintable(&self, querier: &QuerierWrapper) -> bool { + self.minter(querier).is_ok() } } From 2191c7a94edd4d73646314dff502fbe5c4cc721f Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 25 Oct 2022 18:01:13 +0200 Subject: [PATCH 549/631] cw20: style --- packages/cw20/src/helpers.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index 1b1f2c067..78f13a136 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -43,11 +43,11 @@ impl Cw20Contract { } /// Get token balance for the given address - pub fn balance, CQ: CustomQuery>( - &self, - querier: &QuerierWrapper, - address: T, - ) -> StdResult { + pub fn balance(&self, querier: &QuerierWrapper, address: T) -> StdResult + where + T: Into, + CQ: CustomQuery, + { let query = self.encode_smart_query(Cw20QueryMsg::Balance { address: address.into(), })?; @@ -66,12 +66,17 @@ impl Cw20Contract { } /// Get allowance of spender to use owner's account - pub fn allowance, U: Into, CQ: CustomQuery>( + pub fn allowance( &self, querier: &QuerierWrapper, owner: T, spender: U, - ) -> StdResult { + ) -> StdResult + where + T: Into, + U: Into, + CQ: CustomQuery, + { let query = self.encode_smart_query(Cw20QueryMsg::Allowance { owner: owner.into(), spender: spender.into(), From 87df7f2e8b4bdc32267f980392c9690ae1c8db06 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 25 Oct 2022 18:22:47 +0200 Subject: [PATCH 550/631] Use QuerierWrapper not Querier in cw2 helpers --- packages/cw2/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index 12cb7b594..aae498609 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -18,7 +18,7 @@ For more information on this specification, please check out the */ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Empty, Querier, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery}; +use cosmwasm_std::{CustomQuery, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery}; use cw_storage_plus::Item; pub const CONTRACT: Item = Item::new("contract_info"); @@ -59,15 +59,19 @@ pub fn set_contract_version, U: Into>( /// if the other contract exists and claims to be a cw20-base contract for example. /// (Note: you usually want to require *interfaces* not *implementations* of the /// contracts you compose with, so be careful of overuse) -pub fn query_contract_info>( - querier: &Q, +pub fn query_contract_info( + querier: &QuerierWrapper, contract_addr: T, -) -> StdResult { +) -> StdResult +where + T: Into, + CQ: CustomQuery, +{ let req = QueryRequest::Wasm(WasmQuery::Raw { contract_addr: contract_addr.into(), key: CONTRACT.as_slice().into(), }); - QuerierWrapper::::new(querier).query(&req) + querier.query(&req) } #[cfg(test)] From 06f126d9fc7e0ed9d1102b725db8181ba094f464 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 25 Oct 2022 18:29:54 +0200 Subject: [PATCH 551/631] Fix cw3-fixed-multisig --- contracts/cw3-flex-multisig/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 2b473a250..36d4d1afb 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -690,7 +690,7 @@ mod tests { .unwrap(); // Verify contract version set properly - let version = query_contract_info(&app, flex_addr.clone()).unwrap(); + let version = query_contract_info(&app.wrap(), flex_addr.clone()).unwrap(); assert_eq!( ContractVersion { contract: CONTRACT_NAME.to_string(), From 1558f79a4e4878b4f67eda7fa7f233a5c6464ab3 Mon Sep 17 00:00:00 2001 From: Zeke Medley Date: Wed, 6 Jul 2022 17:41:41 -0700 Subject: [PATCH 552/631] Add an optional proposal deposit to cw3-flex-multisig. --- Cargo.lock | 4 + contracts/cw3-fixed-multisig/src/contract.rs | 12 +- contracts/cw3-fixed-multisig/src/state.rs | 571 +---------------- contracts/cw3-flex-multisig/Cargo.toml | 2 + contracts/cw3-flex-multisig/src/contract.rs | 614 ++++++++++++++++++- contracts/cw3-flex-multisig/src/error.rs | 9 +- contracts/cw3-flex-multisig/src/msg.rs | 7 +- contracts/cw3-flex-multisig/src/state.rs | 3 + packages/cw20/Cargo.toml | 3 + packages/cw20/src/denom.rs | 32 +- packages/cw20/src/lib.rs | 2 +- packages/cw3/Cargo.toml | 2 + packages/cw3/src/deposit.rs | 141 +++++ packages/cw3/src/lib.rs | 4 + packages/cw3/src/proposal.rs | 577 +++++++++++++++++ packages/cw3/src/query.rs | 32 +- 16 files changed, 1401 insertions(+), 614 deletions(-) create mode 100644 packages/cw3/src/deposit.rs create mode 100644 packages/cw3/src/proposal.rs diff --git a/Cargo.lock b/Cargo.lock index cc4a30196..c6eb64e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,8 +367,10 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-utils", + "cw20", "schemars", "serde", + "thiserror", ] [[package]] @@ -399,6 +401,8 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw2 0.16.0", + "cw20", + "cw20-base", "cw3", "cw3-fixed-multisig", "cw4", diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index 1b2c19a29..a56d65d1a 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -9,15 +9,15 @@ use cosmwasm_std::{ use cw2::set_contract_version; use cw3::{ - ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, - VoterDetail, VoterListResponse, VoterResponse, + Ballot, Proposal, ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, + VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, Votes, }; use cw_storage_plus::Bound; use cw_utils::{Expiration, ThresholdResponse}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{next_id, Ballot, Config, Proposal, Votes, BALLOTS, CONFIG, PROPOSALS, VOTERS}; +use crate::state::{next_id, Config, BALLOTS, CONFIG, PROPOSALS, VOTERS}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-fixed-multisig"; @@ -112,6 +112,8 @@ pub fn execute_propose( votes: Votes::yes(vote_power), threshold: cfg.threshold, total_weight: cfg.total_weight, + proposer: info.sender.clone(), + deposit: None, }; prop.update_status(&env.block); let id = next_id(deps.storage)?; @@ -276,6 +278,8 @@ fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult msgs: prop.msgs, status, expires: prop.expires, + deposit: prop.deposit, + proposer: prop.proposer, threshold, }) } @@ -331,6 +335,8 @@ fn map_proposal( description: prop.description, msgs: prop.msgs, status, + deposit: prop.deposit, + proposer: prop.proposer, expires: prop.expires, threshold, } diff --git a/contracts/cw3-fixed-multisig/src/state.rs b/contracts/cw3-fixed-multisig/src/state.rs index d0c7914b8..c37775aa8 100644 --- a/contracts/cw3-fixed-multisig/src/state.rs +++ b/contracts/cw3-fixed-multisig/src/state.rs @@ -1,13 +1,9 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; +use cosmwasm_std::{Addr, StdResult, Storage}; -use cw3::{Status, Vote}; +use cw3::{Ballot, Proposal}; use cw_storage_plus::{Item, Map}; -use cw_utils::{Duration, Expiration, Threshold}; - -// we multiply by this when calculating needed_votes in order to round up properly -// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" -const PRECISION_FACTOR: u128 = 1_000_000_000; +use cw_utils::{Duration, Threshold}; #[cw_serde] pub struct Config { @@ -16,164 +12,6 @@ pub struct Config { pub max_voting_period: Duration, } -#[cw_serde] -pub struct Proposal { - pub title: String, - pub description: String, - pub start_height: u64, - pub expires: Expiration, - pub msgs: Vec>, - pub status: Status, - /// pass requirements - pub threshold: Threshold, - // the total weight when the proposal started (used to calculate percentages) - pub total_weight: u64, - // summary of existing votes - pub votes: Votes, -} - -impl Proposal { - /// current_status is non-mutable and returns what the status should be. - /// (designed for queries) - pub fn current_status(&self, block: &BlockInfo) -> Status { - let mut status = self.status; - - // if open, check if voting is passed or timed out - if status == Status::Open && self.is_passed(block) { - status = Status::Passed; - } - if status == Status::Open && (self.is_rejected(block) || self.expires.is_expired(block)) { - status = Status::Rejected; - } - - status - } - - /// update_status sets the status of the proposal to current_status. - /// (designed for handler logic) - pub fn update_status(&mut self, block: &BlockInfo) { - self.status = self.current_status(block); - } - - /// Returns true if this proposal is sure to pass (even before expiration, if no future - /// sequence of possible votes could cause it to fail). - pub fn is_passed(&self, block: &BlockInfo) -> bool { - match self.threshold { - Threshold::AbsoluteCount { - weight: weight_needed, - } => self.votes.yes >= weight_needed, - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => { - self.votes.yes - >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) - } - Threshold::ThresholdQuorum { threshold, quorum } => { - // we always require the quorum - if self.votes.total() < votes_needed(self.total_weight, quorum) { - return false; - } - if self.expires.is_expired(block) { - // If expired, we compare vote_count against the total number of votes (minus abstain). - let opinions = self.votes.total() - self.votes.abstain; - self.votes.yes >= votes_needed(opinions, threshold) - } else { - // If not expired, we must assume all non-votes will be cast against - let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.yes >= votes_needed(possible_opinions, threshold) - } - } - } - } - - /// Returns true if this proposal is sure to be rejected (even before expiration, if - /// no future sequence of possible votes could cause it to pass). - pub fn is_rejected(&self, block: &BlockInfo) -> bool { - match self.threshold { - Threshold::AbsoluteCount { - weight: weight_needed, - } => { - let weight = self.total_weight - weight_needed; - self.votes.no > weight - } - Threshold::AbsolutePercentage { - percentage: percentage_needed, - } => { - self.votes.no - > votes_needed( - self.total_weight - self.votes.abstain, - Decimal::one() - percentage_needed, - ) - } - Threshold::ThresholdQuorum { - threshold, - quorum: _, - } => { - if self.expires.is_expired(block) { - // If expired, we compare vote_count against the total number of votes (minus abstain). - let opinions = self.votes.total() - self.votes.abstain; - self.votes.no > votes_needed(opinions, Decimal::one() - threshold) - } else { - // If not expired, we must assume all non-votes will be cast for - let possible_opinions = self.total_weight - self.votes.abstain; - self.votes.no > votes_needed(possible_opinions, Decimal::one() - threshold) - } - } - } - } -} - -// weight of votes for each option -#[cw_serde] -pub struct Votes { - pub yes: u64, - pub no: u64, - pub abstain: u64, - pub veto: u64, -} - -impl Votes { - /// sum of all votes - pub fn total(&self) -> u64 { - self.yes + self.no + self.abstain + self.veto - } - - /// create it with a yes vote for this much - pub fn yes(init_weight: u64) -> Self { - Votes { - yes: init_weight, - no: 0, - abstain: 0, - veto: 0, - } - } - - pub fn add_vote(&mut self, vote: Vote, weight: u64) { - match vote { - Vote::Yes => self.yes += weight, - Vote::Abstain => self.abstain += weight, - Vote::No => self.no += weight, - Vote::Veto => self.veto += weight, - } - } -} - -// this is a helper function so Decimal works with u64 rather than Uint128 -// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total -fn votes_needed(weight: u64, percentage: Decimal) -> u64 { - let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); - // Divide by PRECISION_FACTOR, rounding up to the nearest integer - ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 -} - -// we cast a ballot with our chosen vote and a given weight -// stored under the key that voted -#[cw_serde] -pub struct Ballot { - pub weight: u64, - pub vote: Vote, -} - // unique items pub const CONFIG: Item = Item::new("config"); pub const PROPOSAL_COUNT: Item = Item::new("proposal_count"); @@ -190,406 +28,3 @@ pub fn next_id(store: &mut dyn Storage) -> StdResult { PROPOSAL_COUNT.save(store, &id)?; Ok(id) } - -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::mock_env; - - #[test] - fn count_votes() { - let mut votes = Votes::yes(5); - votes.add_vote(Vote::No, 10); - votes.add_vote(Vote::Veto, 20); - votes.add_vote(Vote::Yes, 30); - votes.add_vote(Vote::Abstain, 40); - - assert_eq!(votes.total(), 105); - assert_eq!(votes.yes, 35); - assert_eq!(votes.no, 10); - assert_eq!(votes.veto, 20); - assert_eq!(votes.abstain, 40); - } - - #[test] - // we ensure this rounds up (as it calculates needed votes) - fn votes_needed_rounds_properly() { - // round up right below 1 - assert_eq!(1, votes_needed(3, Decimal::permille(333))); - // round up right over 1 - assert_eq!(2, votes_needed(3, Decimal::permille(334))); - assert_eq!(11, votes_needed(30, Decimal::permille(334))); - - // exact matches don't round - assert_eq!(17, votes_needed(34, Decimal::percent(50))); - assert_eq!(12, votes_needed(48, Decimal::percent(25))); - } - - fn setup_prop( - threshold: Threshold, - votes: Votes, - total_weight: u64, - is_expired: bool, - ) -> (Proposal, BlockInfo) { - let block = mock_env().block; - let expires = match is_expired { - true => Expiration::AtHeight(block.height - 5), - false => Expiration::AtHeight(block.height + 100), - }; - let prop = Proposal { - title: "Demo".to_string(), - description: "Info".to_string(), - start_height: 100, - expires, - msgs: vec![], - status: Status::Open, - threshold, - total_weight, - votes, - }; - - (prop, block) - } - - fn check_is_passed( - threshold: Threshold, - votes: Votes, - total_weight: u64, - is_expired: bool, - ) -> bool { - let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); - prop.is_passed(&block) - } - - fn check_is_rejected( - threshold: Threshold, - votes: Votes, - total_weight: u64, - is_expired: bool, - ) -> bool { - let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); - prop.is_rejected(&block) - } - - #[test] - fn proposal_passed_absolute_count() { - let fixed = Threshold::AbsoluteCount { weight: 10 }; - let mut votes = Votes::yes(7); - votes.add_vote(Vote::Veto, 4); - // same expired or not, total_weight or whatever - assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, false)); - assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, true)); - // a few more yes votes and we are good - votes.add_vote(Vote::Yes, 3); - assert!(check_is_passed(fixed.clone(), votes.clone(), 30, false)); - assert!(check_is_passed(fixed, votes, 30, true)); - } - - #[test] - fn proposal_rejected_absolute_count() { - let fixed = Threshold::AbsoluteCount { weight: 10 }; - let mut votes = Votes::yes(0); - votes.add_vote(Vote::Veto, 4); - votes.add_vote(Vote::No, 7); - // In order to reject the proposal we need no votes > 30 - 10, currently it is not rejected - assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, false)); - assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, true)); - // 7 + 14 = 21 > 20, we can now reject - votes.add_vote(Vote::No, 14); - assert!(check_is_rejected(fixed.clone(), votes.clone(), 30, false)); - assert!(check_is_rejected(fixed, votes, 30, true)); - } - - #[test] - fn proposal_passed_absolute_percentage() { - let percent = Threshold::AbsolutePercentage { - percentage: Decimal::percent(50), - }; - let mut votes = Votes::yes(7); - votes.add_vote(Vote::No, 4); - votes.add_vote(Vote::Abstain, 2); - // same expired or not, if yes >= ceiling(0.5 * (total - abstained)) - // 7 of (15-2) passes - assert!(check_is_passed(percent.clone(), votes.clone(), 15, false)); - assert!(check_is_passed(percent.clone(), votes.clone(), 15, true)); - // but 7 of (17-2) fails - assert!(!check_is_passed(percent.clone(), votes.clone(), 17, false)); - - // if the total were a bit lower, this would pass - assert!(check_is_passed(percent.clone(), votes.clone(), 14, false)); - assert!(check_is_passed(percent, votes, 14, true)); - } - - #[test] - fn proposal_rejected_absolute_percentage() { - let percent = Threshold::AbsolutePercentage { - percentage: Decimal::percent(60), - }; - - // 4 YES, 7 NO, 2 ABSTAIN - let mut votes = Votes::yes(4); - votes.add_vote(Vote::No, 7); - votes.add_vote(Vote::Abstain, 2); - - // 15 total voting power - // we need no votes > 0.4 * 15, no votes > 6 - assert!(check_is_rejected(percent.clone(), votes.clone(), 15, false)); - assert!(check_is_rejected(percent.clone(), votes.clone(), 15, true)); - - // 17 total voting power - // we need no votes > 0.4 * 17, no votes > 6.8 - // still rejected - assert!(check_is_rejected(percent.clone(), votes.clone(), 17, false)); - assert!(check_is_rejected(percent.clone(), votes.clone(), 17, true)); - - // Not rejected if total weight is 20 - // as no votes > 0.4 * 18, no votes > 8 - assert!(!check_is_rejected( - percent.clone(), - votes.clone(), - 20, - false - )); - assert!(!check_is_rejected(percent, votes.clone(), 20, true)); - } - - #[test] - fn proposal_passed_quorum() { - let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(50), - quorum: Decimal::percent(40), - }; - // all non-yes votes are counted for quorum - let passing = Votes { - yes: 7, - no: 3, - abstain: 2, - veto: 1, - }; - // abstain votes are not counted for threshold => yes / (yes + no + veto) - let passes_ignoring_abstain = Votes { - yes: 6, - no: 4, - abstain: 5, - veto: 2, - }; - // fails any way you look at it - let failing = Votes { - yes: 6, - no: 5, - abstain: 2, - veto: 2, - }; - - // first, expired (voting period over) - // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) - assert!(check_is_passed(quorum.clone(), passing.clone(), 30, true)); - // under quorum it is not passing (40% of 33 = 13.2 > 13) - assert!(!check_is_passed(quorum.clone(), passing.clone(), 33, true)); - // over quorum, threshold passes if we ignore abstain - // 17 total votes w/ abstain => 40% quorum of 40 total - // 6 yes / (6 yes + 4 no + 2 votes) => 50% threshold - assert!(check_is_passed( - quorum.clone(), - passes_ignoring_abstain.clone(), - 40, - true - )); - // over quorum, but under threshold fails also - assert!(!check_is_passed(quorum.clone(), failing, 20, true)); - - // now, check with open voting period - // would pass if closed, but fail here, as remaining votes no -> fail - assert!(!check_is_passed(quorum.clone(), passing.clone(), 30, false)); - assert!(!check_is_passed( - quorum.clone(), - passes_ignoring_abstain.clone(), - 40, - false - )); - // if we have threshold * total_weight as yes votes this must pass - assert!(check_is_passed(quorum.clone(), passing.clone(), 14, false)); - // all votes have been cast, some abstain - assert!(check_is_passed( - quorum.clone(), - passes_ignoring_abstain, - 17, - false - )); - // 3 votes uncast, if they all vote no, we have 7 yes, 7 no+veto, 2 abstain (out of 16) - assert!(check_is_passed(quorum, passing, 16, false)); - } - - #[test] - fn proposal_rejected_quorum() { - let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(60), - quorum: Decimal::percent(40), - }; - // all non-yes votes are counted for quorum - let rejecting = Votes { - yes: 3, - no: 7, - abstain: 2, - veto: 1, - }; - // abstain votes are not counted for threshold => yes / (yes + no + veto) - let rejected_ignoring_abstain = Votes { - yes: 4, - no: 6, - abstain: 5, - veto: 2, - }; - // fails any way you look at it - let failing = Votes { - yes: 5, - no: 5, - abstain: 2, - veto: 3, - }; - - // first, expired (voting period over) - // over quorum (40% of 30 = 12, 13 votes casted) - // 13 - 2 abstains = 11 - // we need no votes > 0.4 * 11, no votes > 4.4 - // We can reject this - assert!(check_is_rejected( - quorum.clone(), - rejecting.clone(), - 30, - true - )); - - // Under quorum and cannot reject as it is not expired - assert!(!check_is_rejected( - quorum.clone(), - rejecting.clone(), - 50, - false - )); - // Can reject when expired. - assert!(check_is_rejected( - quorum.clone(), - rejecting.clone(), - 50, - true - )); - - // Check edgecase where quorum is not met but we can reject - // 35% vote no - let quorum_edgecase = Threshold::ThresholdQuorum { - threshold: Decimal::percent(67), - quorum: Decimal::percent(40), - }; - assert!(check_is_rejected( - quorum_edgecase, - Votes { - yes: 15, - no: 35, - abstain: 0, - veto: 10 - }, - 100, - true - )); - - // over quorum, threshold passes if we ignore abstain - // 17 total votes > 40% quorum - // 6 no > 0.4 * (6 no + 4 yes + 2 votes) - // 6 > 4.8 - // we can reject - assert!(check_is_rejected( - quorum.clone(), - rejected_ignoring_abstain.clone(), - 40, - true - )); - - // over quorum - // total opinions due to abstains: 13 - // no votes > 0.4 * 13, no votes > 5 to reject, we have 5 exactly so cannot reject - assert!(!check_is_rejected(quorum.clone(), failing, 20, true)); - - // voting period on going - // over quorum (40% of 14 = 5, 13 votes casted) - // 13 - 2 abstains = 11 - // we need no votes > 0.4 * 11, no votes > 4.4 - // We can reject this even when it hasn't expired - assert!(check_is_rejected( - quorum.clone(), - rejecting.clone(), - 14, - false - )); - // all votes have been cast, some abstain - // voting period on going - // over quorum (40% of 17 = 7, 17 casted_ - // 17 - 5 = 12 total opinions - // we need no votes > 0.4 * 12, no votes > 4.8 - // We can reject this even when it hasn't expired - assert!(check_is_rejected( - quorum.clone(), - rejected_ignoring_abstain, - 17, - false - )); - - // 3 votes uncast, if they all vote yes, we have 7 no, 7 yes+veto, 2 abstain (out of 16) - assert!(check_is_rejected(quorum, rejecting, 16, false)); - } - - #[test] - fn quorum_edge_cases() { - // when we pass absolute threshold (everyone else voting no, we pass), but still don't hit quorum - let quorum = Threshold::ThresholdQuorum { - threshold: Decimal::percent(60), - quorum: Decimal::percent(80), - }; - - // try 9 yes, 1 no (out of 15) -> 90% voter threshold, 60% absolute threshold, still no quorum - // doesn't matter if expired or not - let missing_voters = Votes { - yes: 9, - no: 1, - abstain: 0, - veto: 0, - }; - assert!(!check_is_passed( - quorum.clone(), - missing_voters.clone(), - 15, - false - )); - assert!(!check_is_passed(quorum.clone(), missing_voters, 15, true)); - - // 1 less yes, 3 vetos and this passes only when expired - let wait_til_expired = Votes { - yes: 8, - no: 1, - abstain: 0, - veto: 3, - }; - assert!(!check_is_passed( - quorum.clone(), - wait_til_expired.clone(), - 15, - false - )); - assert!(check_is_passed(quorum.clone(), wait_til_expired, 15, true)); - - // 9 yes and 3 nos passes early - let passes_early = Votes { - yes: 9, - no: 3, - abstain: 0, - veto: 0, - }; - assert!(check_is_passed( - quorum.clone(), - passes_early.clone(), - 15, - false - )); - assert!(check_is_passed(quorum, passes_early, 15, true)); - } -} diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 076bd6638..46d8411ca 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -24,6 +24,7 @@ cw2 = { path = "../../packages/cw2", version = "0.16.0" } cw3 = { path = "../../packages/cw3", version = "0.16.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.16.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "0.16.0" } +cw20 = { path = "../../packages/cw20", version = "0.16.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -33,3 +34,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cw4-group = { path = "../cw4-group", version = "0.16.0" } cw-multi-test = "0.16.0" +cw20-base = { path = "../cw20-base", version = "0.16.0" } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 2b473a250..253b20f1c 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -8,11 +8,12 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; + use cw3::{ - ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, - VoterDetail, VoterListResponse, VoterResponse, + Ballot, Proposal, ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, + VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, Votes, }; -use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; +use cw3_fixed_multisig::state::{next_id, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; @@ -40,6 +41,11 @@ pub fn instantiate( let total_weight = group_addr.total_weight(&deps.querier)?; msg.threshold.validate(total_weight)?; + let proposal_deposit = msg + .proposal_deposit + .map(|deposit| deposit.into_checked(deps.as_ref())) + .transpose()?; + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { @@ -47,6 +53,7 @@ pub fn instantiate( max_voting_period: msg.max_voting_period, group_addr, executor: msg.executor, + proposal_deposit, }; CONFIG.save(deps.storage, &cfg)?; @@ -89,6 +96,11 @@ pub fn execute_propose( // only members of the multisig can create a proposal let cfg = CONFIG.load(deps.storage)?; + // Check that the native deposit was paid (as needed). + if let Some(deposit) = cfg.proposal_deposit.as_ref() { + deposit.check_native_deposit_paid(&info)?; + } + // Only members of the multisig can create a proposal // Non-voting members are special - they are allowed to create a proposal and // therefore "vote", but they aren't allowed to vote otherwise. @@ -109,6 +121,15 @@ pub fn execute_propose( return Err(ContractError::WrongExpiration {}); } + // Take the cw20 token deposit, if required. We do this before + // creating the proposal struct below so that we can avoid a clone + // and move the loaded deposit info into it. + let take_deposit_msg = if let Some(deposit_info) = cfg.proposal_deposit.as_ref() { + deposit_info.get_take_deposit_messages(&info.sender, &env.contract.address)? + } else { + vec![] + }; + // create a proposal let mut prop = Proposal { title, @@ -120,6 +141,8 @@ pub fn execute_propose( votes: Votes::yes(vote_power), threshold: cfg.threshold, total_weight: cfg.group_addr.total_weight(&deps.querier)?, + proposer: info.sender.clone(), + deposit: cfg.proposal_deposit, }; prop.update_status(&env.block); let id = next_id(deps.storage)?; @@ -133,6 +156,7 @@ pub fn execute_propose( BALLOTS.save(deps.storage, (id, &info.sender), &ballot)?; Ok(Response::new() + .add_messages(take_deposit_msg) .add_attribute("action", "propose") .add_attribute("sender", info.sender) .add_attribute("proposal_id", id.to_string()) @@ -210,8 +234,16 @@ pub fn execute_execute( prop.status = Status::Executed; PROPOSALS.save(deps.storage, proposal_id, &prop)?; + // Unconditionally refund here. + let response = match prop.deposit { + Some(deposit) => { + Response::new().add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + None => Response::new(), + }; + // dispatch all proposed messages - Ok(Response::new() + Ok(response .add_messages(prop.msgs) .add_attribute("action", "execute") .add_attribute("sender", info.sender) @@ -242,7 +274,15 @@ pub fn execute_close( prop.status = Status::Rejected; PROPOSALS.save(deps.storage, proposal_id, &prop)?; - Ok(Response::new() + // Refund the deposit if we have been configured to do so. + let mut response = Response::new(); + if let Some(deposit) = prop.deposit { + if deposit.refund_failed_proposals { + response = response.add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + } + + Ok(response .add_attribute("action", "close") .add_attribute("sender", info.sender) .add_attribute("proposal_id", proposal_id.to_string())) @@ -286,6 +326,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ListVoters { start_after, limit } => { to_binary(&list_voters(deps, start_after, limit)?) } + QueryMsg::Config {} => to_binary(&query_config(deps)?), } } @@ -295,6 +336,10 @@ fn query_threshold(deps: Deps) -> StdResult { Ok(cfg.threshold.to_response(total_weight)) } +fn query_config(deps: Deps) -> StdResult { + CONFIG.load(deps.storage) +} + fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult { let prop = PROPOSALS.load(deps.storage, id)?; let status = prop.current_status(&env.block); @@ -306,6 +351,8 @@ fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult msgs: prop.msgs, status, expires: prop.expires, + proposer: prop.proposer, + deposit: prop.deposit, threshold, }) } @@ -362,6 +409,8 @@ fn map_proposal( msgs: prop.msgs, status, expires: prop.expires, + deposit: prop.deposit, + proposer: prop.proposer, threshold, } }) @@ -434,12 +483,16 @@ fn list_voters( #[cfg(test)] mod tests { - use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp}; + use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp, Uint128}; use cw2::{query_contract_info, ContractVersion}; + use cw20::{Cw20Coin, UncheckedDenom}; + use cw3::{DepositError, UncheckedDepositInfo}; use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; - use cw_multi_test::{next_block, App, AppBuilder, Contract, ContractWrapper, Executor}; + use cw_multi_test::{ + next_block, App, AppBuilder, BankSudo, Contract, ContractWrapper, Executor, SudoMsg, + }; use cw_utils::{Duration, Threshold}; use super::*; @@ -477,6 +530,15 @@ mod tests { Box::new(contract) } + fn contract_cw20() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) + } + fn mock_app(init_funds: &[Coin]) -> App { AppBuilder::new().build(|router, _, storage| { router @@ -504,6 +566,7 @@ mod tests { threshold: Threshold, max_voting_period: Duration, executor: Option, + proposal_deposit: Option, ) -> Addr { let flex_id = app.store_code(contract_flex()); let msg = crate::msg::InstantiateMsg { @@ -511,6 +574,7 @@ mod tests { threshold, max_voting_period, executor, + proposal_deposit, }; app.instantiate_contract(flex_id, Addr::unchecked(OWNER), &msg, &[], "flex", None) .unwrap() @@ -536,6 +600,7 @@ mod tests { init_funds, multisig_as_group_admin, None, + None, ) } @@ -547,6 +612,7 @@ mod tests { init_funds: Vec, multisig_as_group_admin: bool, executor: Option, + proposal_deposit: Option, ) -> (Addr, Addr) { // 1. Instantiate group contract with members (and OWNER as admin) let members = vec![ @@ -567,6 +633,7 @@ mod tests { threshold, max_voting_period, executor, + proposal_deposit, ); app.update_block(next_block); @@ -614,6 +681,16 @@ mod tests { } } + fn text_proposal() -> ExecuteMsg { + let (_, title, description) = proposal_info(); + ExecuteMsg::Propose { + title, + description, + msgs: vec![], + latest: None, + } + } + #[test] fn test_instantiate_works() { let mut app = mock_app(&[]); @@ -633,6 +710,7 @@ mod tests { }, max_voting_period, executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -655,6 +733,7 @@ mod tests { threshold: Threshold::AbsoluteCount { weight: 100 }, max_voting_period, executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -677,6 +756,7 @@ mod tests { threshold: Threshold::AbsoluteCount { weight: 1 }, max_voting_period, executor: None, + proposal_deposit: None, }; let flex_addr = app .instantiate_contract( @@ -834,8 +914,15 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }; - let (flex_addr, _) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 1 vote power let proposal = pay_somebody_proposal(); @@ -916,6 +1003,8 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }, + proposer: Addr::unchecked(VOTER2), + deposit: None, }; assert_eq!(&expected, &res.proposals[0]); } @@ -930,8 +1019,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); @@ -1150,8 +1246,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = - setup_test_case(&mut app, threshold, voting_period, init_funds, true, None); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // ensure we have cash to cover the proposal let contract_bal = app.wrap().query_balance(&flex_addr, "BTC").unwrap(); @@ -1258,6 +1361,7 @@ mod tests { init_funds, true, Some(crate::state::Executor::Member), // set executor as Member of voting group + None, ); // create proposal with 0 vote power @@ -1314,6 +1418,7 @@ mod tests { init_funds, true, Some(crate::state::Executor::Only(Addr::unchecked(VOTER3))), // only VOTER3 can execute proposal + None, ); // create proposal with 0 vote power @@ -1380,6 +1485,7 @@ mod tests { init_funds, true, None, + None, ); // ensure we have cash to cover the proposal @@ -1466,8 +1572,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Height(2000000); - let (flex_addr, _) = - setup_test_case(&mut app, threshold, voting_period, init_funds, true, None); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); @@ -1518,8 +1631,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER1 starts a proposal to send some tokens (1/4 votes) let proposal = pay_somebody_proposal(); @@ -1764,8 +1884,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false, None); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER3 starts a proposal to send some tokens (3/12 votes) let proposal = pay_somebody_proposal(); @@ -1849,6 +1976,7 @@ mod tests { init_funds, false, None, + None, ); // VOTER3 starts a proposal to send some tokens (3 votes) @@ -1920,6 +2048,7 @@ mod tests { init_funds, false, None, + None, ); // create proposal @@ -1959,4 +2088,451 @@ mod tests { .unwrap(); assert_eq!(prop_status(&app), Status::Passed); } + + #[test] + fn test_instantiate_with_invalid_deposit() { + let mut app = App::default(); + + let flex_id = app.store_code(contract_flex()); + + let group_addr = instantiate_group( + &mut app, + vec![Member { + addr: OWNER.to_string(), + weight: 10, + }], + ); + + // Instantiate with an invalid cw20 token. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::new(1), + refund_failed_proposals: true, + denom: UncheckedDenom::Cw20(group_addr.to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::InvalidCw20 {})); + + // Instantiate with a zero amount. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::zero(), + refund_failed_proposals: true, + denom: UncheckedDenom::Native("native".to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::ZeroDeposit {})) + } + + #[test] + fn test_cw20_proposal_deposit() { + let mut app = App::default(); + + let cw20_id = app.store_code(contract_cw20()); + + let cw20_addr = app + .instantiate_contract( + cw20_id, + Addr::unchecked(OWNER), + &cw20_base::msg::InstantiateMsg { + name: "Token".to_string(), + symbol: "TOKEN".to_string(), + decimals: 6, + initial_balances: vec![ + Cw20Coin { + address: VOTER4.to_string(), + amount: Uint128::new(10), + }, + Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(10), + }, + ], + mint: None, + marketing: None, + }, + &[], + "Token", + None, + ) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Cw20(cw20_addr.to_string()), + refund_failed_proposals: true, + }), + ); + + app.execute_contract( + Addr::unchecked(VOTER4), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that will pass. + let proposal = text_proposal(); + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Make sure the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + app.execute_contract( + Addr::unchecked(OWNER), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) + .unwrap(); + + // Check that the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr, + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + } + + #[test] + fn proposal_deposit_no_failed_refunds() { + let mut app = App::default(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: false, + }), + ); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: OWNER.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(OWNER), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + // Check that the deposit was transfered. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 1, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Check that the deposit wasn't returned. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + } + + #[test] + fn test_native_proposal_deposit() { + let mut app = App::default(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: VOTER4.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: OWNER.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: true, + }), + ); + + // Make a proposal that will pass. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + // Make sure the deposit was transfered. + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance = app.wrap().query_balance(VOTER4, "TOKEN").unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(OWNER), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance = app.wrap().query_balance(OWNER, "TOKEN").unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + } } diff --git a/contracts/cw3-flex-multisig/src/error.rs b/contracts/cw3-flex-multisig/src/error.rs index 4936a8923..3463a6ec8 100644 --- a/contracts/cw3-flex-multisig/src/error.rs +++ b/contracts/cw3-flex-multisig/src/error.rs @@ -1,5 +1,6 @@ use cosmwasm_std::StdError; -use cw_utils::ThresholdError; +use cw3::DepositError; +use cw_utils::{PaymentError, ThresholdError}; use thiserror::Error; @@ -37,4 +38,10 @@ pub enum ContractError { #[error("Cannot close completed or passed proposals")] WrongCloseStatus {}, + + #[error("{0}")] + Payment(#[from] PaymentError), + + #[error("{0}")] + Deposit(#[from] DepositError), } diff --git a/contracts/cw3-flex-multisig/src/msg.rs b/contracts/cw3-flex-multisig/src/msg.rs index f91e8abff..f488e2813 100644 --- a/contracts/cw3-flex-multisig/src/msg.rs +++ b/contracts/cw3-flex-multisig/src/msg.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::Vote; +use cw3::{UncheckedDepositInfo, Vote}; use cw4::MemberChangedHookMsg; use cw_utils::{Duration, Expiration, Threshold}; @@ -15,6 +15,8 @@ pub struct InstantiateMsg { // who is able to execute passed proposals // None means that anyone can execute pub executor: Option, + /// The cost of creating a proposal (if any). + pub proposal_deposit: Option, } // TODO: add some T variants? Maybe good enough as fixed Empty for now @@ -74,4 +76,7 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + /// Gets the current configuration. + #[returns(crate::state::Config)] + Config {}, } diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index e6dc06bd8..506bc6311 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, QuerierWrapper}; +use cw3::DepositInfo; use cw4::Cw4Contract; use cw_storage_plus::Item; use cw_utils::{Duration, Threshold}; @@ -24,6 +25,8 @@ pub struct Config { // who is able to execute passed proposals // None means that anyone can execute pub executor: Option, + /// The price, if any, of creating a new proposal. + pub proposal_deposit: Option, } impl Config { diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index a71df10b1..fb9534e18 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -14,3 +14,6 @@ cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } + +[dev-dependencies] +cosmwasm-schema = { version = "1.0.0" } diff --git a/packages/cw20/src/denom.rs b/packages/cw20/src/denom.rs index f0351c665..abc9972b4 100644 --- a/packages/cw20/src/denom.rs +++ b/packages/cw20/src/denom.rs @@ -1,13 +1,41 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; +use cosmwasm_std::{Addr, Deps, StdResult, Uint128}; -#[cw_serde] +use crate::{Cw20QueryMsg, TokenInfoResponse}; +#[cw_serde] pub enum Denom { Native(String), Cw20(Addr), } +#[cw_serde] +pub enum UncheckedDenom { + Native(String), + Cw20(String), +} + +#[cw_serde] +pub struct DepositInfo { + amount: Uint128, + denom: UncheckedDenom, +} + +impl UncheckedDenom { + pub fn into_checked(self, deps: Deps) -> StdResult { + match self { + Self::Native(denom) => Ok(Denom::Native(denom)), + Self::Cw20(addr) => { + let addr = deps.api.addr_validate(&addr)?; + let _info: TokenInfoResponse = deps + .querier + .query_wasm_smart(addr.clone(), &Cw20QueryMsg::TokenInfo {})?; + Ok(Denom::Cw20(addr)) + } + } + } +} + // TODO: remove or figure out where needed impl Default for Denom { fn default() -> Denom { diff --git a/packages/cw20/src/lib.rs b/packages/cw20/src/lib.rs index f99ea08a3..2d94a6a94 100644 --- a/packages/cw20/src/lib.rs +++ b/packages/cw20/src/lib.rs @@ -13,7 +13,7 @@ pub use cw_utils::Expiration; pub use crate::balance::Balance; pub use crate::coin::{Cw20Coin, Cw20CoinVerified}; -pub use crate::denom::Denom; +pub use crate::denom::{Denom, UncheckedDenom}; pub use crate::helpers::Cw20Contract; pub use crate::logo::{EmbeddedLogo, Logo, LogoInfo}; pub use crate::msg::Cw20ExecuteMsg; diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 2835d3268..61c1a8ad4 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -10,7 +10,9 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "0.16.0" +cw20 = { path = "../../packages/cw20", version = "0.16.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.23" } diff --git a/packages/cw3/src/deposit.rs b/packages/cw3/src/deposit.rs new file mode 100644 index 000000000..8cdf0c415 --- /dev/null +++ b/packages/cw3/src/deposit.rs @@ -0,0 +1,141 @@ +use cosmwasm_schema::cw_serde; +use cw_utils::{must_pay, PaymentError}; +use thiserror::Error; + +use cosmwasm_std::{ + to_binary, Addr, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, StdResult, Uint128, WasmMsg, +}; +use cw20::{Denom, UncheckedDenom}; + +/// Information about the deposit required to create a proposal. +#[cw_serde] +pub struct DepositInfo { + /// The number tokens required for payment. + pub amount: Uint128, + /// The denom of the deposit payment. + pub denom: Denom, + /// Should failed proposals have their deposits refunded? + pub refund_failed_proposals: bool, +} + +/// Information about the deposit required to create a proposal. For +/// use in messages. To validate, transform into `DepositInfo` via +/// `into_checked()`. +#[cw_serde] +pub struct UncheckedDepositInfo { + /// The number tokens required for payment. + pub amount: Uint128, + /// The denom of the deposit payment. + pub denom: UncheckedDenom, + /// Should failed proposals have their deposits refunded? + pub refund_failed_proposals: bool, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum DepositError { + #[error("Invalid zero deposit. Set the deposit to None to have no deposit.")] + ZeroDeposit {}, + + #[error("Invalid cw20")] + InvalidCw20 {}, + + #[error("{0}")] + Payment(#[from] PaymentError), + + #[error("Invalid native deposit amount")] + InvalidDeposit {}, +} + +impl UncheckedDepositInfo { + /// Checks deposit info. + pub fn into_checked(self, deps: Deps) -> Result { + if self.amount.is_zero() { + Err(DepositError::ZeroDeposit {}) + } else { + Ok(DepositInfo { + amount: self.amount, + denom: self + .denom + .into_checked(deps) + .map_err(|_| DepositError::InvalidCw20 {})?, + refund_failed_proposals: self.refund_failed_proposals, + }) + } + } +} + +impl DepositInfo { + pub fn check_native_deposit_paid(&self, info: &MessageInfo) -> Result<(), DepositError> { + if let Self { + amount, + denom: Denom::Native(denom), + .. + } = self + { + let paid = must_pay(info, denom)?; + if paid != *amount { + Err(DepositError::InvalidDeposit {}) + } else { + Ok(()) + } + } else { + Ok(()) + } + } + + pub fn get_take_deposit_messages( + &self, + depositor: &Addr, + contract: &Addr, + ) -> StdResult> { + let take_deposit_msg: Vec = if let DepositInfo { + amount, + denom: Denom::Cw20(address), + .. + } = self + { + // into_checked() makes sure this isn't the case, but just for + // posterity. + if amount.is_zero() { + vec![] + } else { + vec![WasmMsg::Execute { + contract_addr: address.to_string(), + funds: vec![], + msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + owner: depositor.to_string(), + recipient: contract.to_string(), + amount: *amount, + })?, + } + .into()] + } + } else { + vec![] + }; + Ok(take_deposit_msg) + } + + pub fn get_return_deposit_message(&self, depositor: &Addr) -> StdResult { + let message = match &self.denom { + Denom::Native(denom) => BankMsg::Send { + to_address: depositor.to_string(), + amount: vec![Coin { + amount: self.amount, + denom: denom.to_string(), + }], + } + .into(), + Denom::Cw20(address) => WasmMsg::Execute { + contract_addr: address.to_string(), + msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + recipient: depositor.to_string(), + amount: self.amount, + })?, + funds: vec![], + } + .into(), + }; + Ok(message) + } +} diff --git a/packages/cw3/src/lib.rs b/packages/cw3/src/lib.rs index 0740a8e44..7d43cc0bc 100644 --- a/packages/cw3/src/lib.rs +++ b/packages/cw3/src/lib.rs @@ -10,12 +10,16 @@ For more information on this specification, please check out the */ // mod helpers; +mod deposit; mod helpers; mod msg; +mod proposal; mod query; +pub use crate::deposit::{DepositError, DepositInfo, UncheckedDepositInfo}; pub use crate::helpers::Cw3Contract; pub use crate::msg::{Cw3ExecuteMsg, Vote}; +pub use crate::proposal::{Ballot, Proposal, Votes}; pub use crate::query::{ Cw3QueryMsg, ProposalListResponse, ProposalResponse, Status, VoteInfo, VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, diff --git a/packages/cw3/src/proposal.rs b/packages/cw3/src/proposal.rs new file mode 100644 index 000000000..4aa0c812f --- /dev/null +++ b/packages/cw3/src/proposal.rs @@ -0,0 +1,577 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, Uint128}; +use cw_utils::{Expiration, Threshold}; + +use crate::{DepositInfo, Status, Vote}; + +// we multiply by this when calculating needed_votes in order to round up properly +// Note: `10u128.pow(9)` fails as "u128::pow` is not yet stable as a const fn" +const PRECISION_FACTOR: u128 = 1_000_000_000; + +#[cw_serde] +pub struct Proposal { + pub title: String, + pub description: String, + pub start_height: u64, + pub expires: Expiration, + pub msgs: Vec>, + pub status: Status, + /// pass requirements + pub threshold: Threshold, + // the total weight when the proposal started (used to calculate percentages) + pub total_weight: u64, + // summary of existing votes + pub votes: Votes, + /// The address that created the proposal. + pub proposer: Addr, + /// The deposit that was paid along with this proposal. This may + /// be refunded upon proposal completion. + pub deposit: Option, +} + +impl Proposal { + /// current_status is non-mutable and returns what the status should be. + /// (designed for queries) + pub fn current_status(&self, block: &BlockInfo) -> Status { + let mut status = self.status; + + // if open, check if voting is passed or timed out + if status == Status::Open && self.is_passed(block) { + status = Status::Passed; + } + if status == Status::Open && (self.is_rejected(block) || self.expires.is_expired(block)) { + status = Status::Rejected; + } + + status + } + + /// update_status sets the status of the proposal to current_status. + /// (designed for handler logic) + pub fn update_status(&mut self, block: &BlockInfo) { + self.status = self.current_status(block); + } + + /// Returns true if this proposal is sure to pass (even before expiration, if no future + /// sequence of possible votes could cause it to fail). + pub fn is_passed(&self, block: &BlockInfo) -> bool { + match self.threshold { + Threshold::AbsoluteCount { + weight: weight_needed, + } => self.votes.yes >= weight_needed, + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => { + self.votes.yes + >= votes_needed(self.total_weight - self.votes.abstain, percentage_needed) + } + Threshold::ThresholdQuorum { threshold, quorum } => { + // we always require the quorum + if self.votes.total() < votes_needed(self.total_weight, quorum) { + return false; + } + if self.expires.is_expired(block) { + // If expired, we compare vote_count against the total number of votes (minus abstain). + let opinions = self.votes.total() - self.votes.abstain; + self.votes.yes >= votes_needed(opinions, threshold) + } else { + // If not expired, we must assume all non-votes will be cast against + let possible_opinions = self.total_weight - self.votes.abstain; + self.votes.yes >= votes_needed(possible_opinions, threshold) + } + } + } + } + + /// Returns true if this proposal is sure to be rejected (even before expiration, if + /// no future sequence of possible votes could cause it to pass). + pub fn is_rejected(&self, block: &BlockInfo) -> bool { + match self.threshold { + Threshold::AbsoluteCount { + weight: weight_needed, + } => { + let weight = self.total_weight - weight_needed; + self.votes.no > weight + } + Threshold::AbsolutePercentage { + percentage: percentage_needed, + } => { + self.votes.no + > votes_needed( + self.total_weight - self.votes.abstain, + Decimal::one() - percentage_needed, + ) + } + Threshold::ThresholdQuorum { + threshold, + quorum: _, + } => { + if self.expires.is_expired(block) { + // If expired, we compare vote_count against the total number of votes (minus abstain). + let opinions = self.votes.total() - self.votes.abstain; + self.votes.no > votes_needed(opinions, Decimal::one() - threshold) + } else { + // If not expired, we must assume all non-votes will be cast for + let possible_opinions = self.total_weight - self.votes.abstain; + self.votes.no > votes_needed(possible_opinions, Decimal::one() - threshold) + } + } + } + } +} + +// weight of votes for each option +#[cw_serde] +pub struct Votes { + pub yes: u64, + pub no: u64, + pub abstain: u64, + pub veto: u64, +} + +impl Votes { + /// sum of all votes + pub fn total(&self) -> u64 { + self.yes + self.no + self.abstain + self.veto + } + + /// create it with a yes vote for this much + pub fn yes(init_weight: u64) -> Self { + Votes { + yes: init_weight, + no: 0, + abstain: 0, + veto: 0, + } + } + + pub fn add_vote(&mut self, vote: Vote, weight: u64) { + match vote { + Vote::Yes => self.yes += weight, + Vote::Abstain => self.abstain += weight, + Vote::No => self.no += weight, + Vote::Veto => self.veto += weight, + } + } +} + +// this is a helper function so Decimal works with u64 rather than Uint128 +// also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total +fn votes_needed(weight: u64, percentage: Decimal) -> u64 { + let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); + // Divide by PRECISION_FACTOR, rounding up to the nearest integer + ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 +} + +// we cast a ballot with our chosen vote and a given weight +// stored under the key that voted +#[cw_serde] +pub struct Ballot { + pub weight: u64, + pub vote: Vote, +} + +#[cfg(test)] +mod test { + use super::*; + use cosmwasm_std::testing::mock_env; + + #[test] + fn count_votes() { + let mut votes = Votes::yes(5); + votes.add_vote(Vote::No, 10); + votes.add_vote(Vote::Veto, 20); + votes.add_vote(Vote::Yes, 30); + votes.add_vote(Vote::Abstain, 40); + + assert_eq!(votes.total(), 105); + assert_eq!(votes.yes, 35); + assert_eq!(votes.no, 10); + assert_eq!(votes.veto, 20); + assert_eq!(votes.abstain, 40); + } + + #[test] + // we ensure this rounds up (as it calculates needed votes) + fn votes_needed_rounds_properly() { + // round up right below 1 + assert_eq!(1, votes_needed(3, Decimal::permille(333))); + // round up right over 1 + assert_eq!(2, votes_needed(3, Decimal::permille(334))); + assert_eq!(11, votes_needed(30, Decimal::permille(334))); + + // exact matches don't round + assert_eq!(17, votes_needed(34, Decimal::percent(50))); + assert_eq!(12, votes_needed(48, Decimal::percent(25))); + } + + fn setup_prop( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> (Proposal, BlockInfo) { + let block = mock_env().block; + let expires = match is_expired { + true => Expiration::AtHeight(block.height - 5), + false => Expiration::AtHeight(block.height + 100), + }; + let prop = Proposal { + title: "Demo".to_string(), + description: "Info".to_string(), + start_height: 100, + expires, + msgs: vec![], + status: Status::Open, + proposer: Addr::unchecked("Proposer"), + deposit: None, + threshold, + total_weight, + votes, + }; + + (prop, block) + } + + fn check_is_passed( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> bool { + let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); + prop.is_passed(&block) + } + + fn check_is_rejected( + threshold: Threshold, + votes: Votes, + total_weight: u64, + is_expired: bool, + ) -> bool { + let (prop, block) = setup_prop(threshold, votes, total_weight, is_expired); + prop.is_rejected(&block) + } + + #[test] + fn proposal_passed_absolute_count() { + let fixed = Threshold::AbsoluteCount { weight: 10 }; + let mut votes = Votes::yes(7); + votes.add_vote(Vote::Veto, 4); + // same expired or not, total_weight or whatever + assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, false)); + assert!(!check_is_passed(fixed.clone(), votes.clone(), 30, true)); + // a few more yes votes and we are good + votes.add_vote(Vote::Yes, 3); + assert!(check_is_passed(fixed.clone(), votes.clone(), 30, false)); + assert!(check_is_passed(fixed, votes, 30, true)); + } + + #[test] + fn proposal_rejected_absolute_count() { + let fixed = Threshold::AbsoluteCount { weight: 10 }; + let mut votes = Votes::yes(0); + votes.add_vote(Vote::Veto, 4); + votes.add_vote(Vote::No, 7); + // In order to reject the proposal we need no votes > 30 - 10, currently it is not rejected + assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, false)); + assert!(!check_is_rejected(fixed.clone(), votes.clone(), 30, true)); + // 7 + 14 = 21 > 20, we can now reject + votes.add_vote(Vote::No, 14); + assert!(check_is_rejected(fixed.clone(), votes.clone(), 30, false)); + assert!(check_is_rejected(fixed, votes, 30, true)); + } + + #[test] + fn proposal_passed_absolute_percentage() { + let percent = Threshold::AbsolutePercentage { + percentage: Decimal::percent(50), + }; + let mut votes = Votes::yes(7); + votes.add_vote(Vote::No, 4); + votes.add_vote(Vote::Abstain, 2); + // same expired or not, if yes >= ceiling(0.5 * (total - abstained)) + // 7 of (15-2) passes + assert!(check_is_passed(percent.clone(), votes.clone(), 15, false)); + assert!(check_is_passed(percent.clone(), votes.clone(), 15, true)); + // but 7 of (17-2) fails + assert!(!check_is_passed(percent.clone(), votes.clone(), 17, false)); + + // if the total were a bit lower, this would pass + assert!(check_is_passed(percent.clone(), votes.clone(), 14, false)); + assert!(check_is_passed(percent, votes, 14, true)); + } + + #[test] + fn proposal_rejected_absolute_percentage() { + let percent = Threshold::AbsolutePercentage { + percentage: Decimal::percent(60), + }; + + // 4 YES, 7 NO, 2 ABSTAIN + let mut votes = Votes::yes(4); + votes.add_vote(Vote::No, 7); + votes.add_vote(Vote::Abstain, 2); + + // 15 total voting power + // we need no votes > 0.4 * 15, no votes > 6 + assert!(check_is_rejected(percent.clone(), votes.clone(), 15, false)); + assert!(check_is_rejected(percent.clone(), votes.clone(), 15, true)); + + // 17 total voting power + // we need no votes > 0.4 * 17, no votes > 6.8 + // still rejected + assert!(check_is_rejected(percent.clone(), votes.clone(), 17, false)); + assert!(check_is_rejected(percent.clone(), votes.clone(), 17, true)); + + // Not rejected if total weight is 20 + // as no votes > 0.4 * 18, no votes > 8 + assert!(!check_is_rejected( + percent.clone(), + votes.clone(), + 20, + false + )); + assert!(!check_is_rejected(percent, votes.clone(), 20, true)); + } + + #[test] + fn proposal_passed_quorum() { + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(50), + quorum: Decimal::percent(40), + }; + // all non-yes votes are counted for quorum + let passing = Votes { + yes: 7, + no: 3, + abstain: 2, + veto: 1, + }; + // abstain votes are not counted for threshold => yes / (yes + no + veto) + let passes_ignoring_abstain = Votes { + yes: 6, + no: 4, + abstain: 5, + veto: 2, + }; + // fails any way you look at it + let failing = Votes { + yes: 6, + no: 5, + abstain: 2, + veto: 2, + }; + + // first, expired (voting period over) + // over quorum (40% of 30 = 12), over threshold (7/11 > 50%) + assert!(check_is_passed(quorum.clone(), passing.clone(), 30, true)); + // under quorum it is not passing (40% of 33 = 13.2 > 13) + assert!(!check_is_passed(quorum.clone(), passing.clone(), 33, true)); + // over quorum, threshold passes if we ignore abstain + // 17 total votes w/ abstain => 40% quorum of 40 total + // 6 yes / (6 yes + 4 no + 2 votes) => 50% threshold + assert!(check_is_passed( + quorum.clone(), + passes_ignoring_abstain.clone(), + 40, + true + )); + // over quorum, but under threshold fails also + assert!(!check_is_passed(quorum.clone(), failing, 20, true)); + + // now, check with open voting period + // would pass if closed, but fail here, as remaining votes no -> fail + assert!(!check_is_passed(quorum.clone(), passing.clone(), 30, false)); + assert!(!check_is_passed( + quorum.clone(), + passes_ignoring_abstain.clone(), + 40, + false + )); + // if we have threshold * total_weight as yes votes this must pass + assert!(check_is_passed(quorum.clone(), passing.clone(), 14, false)); + // all votes have been cast, some abstain + assert!(check_is_passed( + quorum.clone(), + passes_ignoring_abstain, + 17, + false + )); + // 3 votes uncast, if they all vote no, we have 7 yes, 7 no+veto, 2 abstain (out of 16) + assert!(check_is_passed(quorum, passing, 16, false)); + } + + #[test] + fn proposal_rejected_quorum() { + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(60), + quorum: Decimal::percent(40), + }; + // all non-yes votes are counted for quorum + let rejecting = Votes { + yes: 3, + no: 7, + abstain: 2, + veto: 1, + }; + // abstain votes are not counted for threshold => yes / (yes + no + veto) + let rejected_ignoring_abstain = Votes { + yes: 4, + no: 6, + abstain: 5, + veto: 2, + }; + // fails any way you look at it + let failing = Votes { + yes: 5, + no: 5, + abstain: 2, + veto: 3, + }; + + // first, expired (voting period over) + // over quorum (40% of 30 = 12, 13 votes casted) + // 13 - 2 abstains = 11 + // we need no votes > 0.4 * 11, no votes > 4.4 + // We can reject this + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 30, + true + )); + + // Under quorum and cannot reject as it is not expired + assert!(!check_is_rejected( + quorum.clone(), + rejecting.clone(), + 50, + false + )); + // Can reject when expired. + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 50, + true + )); + + // Check edgecase where quorum is not met but we can reject + // 35% vote no + let quorum_edgecase = Threshold::ThresholdQuorum { + threshold: Decimal::percent(67), + quorum: Decimal::percent(40), + }; + assert!(check_is_rejected( + quorum_edgecase, + Votes { + yes: 15, + no: 35, + abstain: 0, + veto: 10 + }, + 100, + true + )); + + // over quorum, threshold passes if we ignore abstain + // 17 total votes > 40% quorum + // 6 no > 0.4 * (6 no + 4 yes + 2 votes) + // 6 > 4.8 + // we can reject + assert!(check_is_rejected( + quorum.clone(), + rejected_ignoring_abstain.clone(), + 40, + true + )); + + // over quorum + // total opinions due to abstains: 13 + // no votes > 0.4 * 13, no votes > 5 to reject, we have 5 exactly so cannot reject + assert!(!check_is_rejected(quorum.clone(), failing, 20, true)); + + // voting period on going + // over quorum (40% of 14 = 5, 13 votes casted) + // 13 - 2 abstains = 11 + // we need no votes > 0.4 * 11, no votes > 4.4 + // We can reject this even when it hasn't expired + assert!(check_is_rejected( + quorum.clone(), + rejecting.clone(), + 14, + false + )); + // all votes have been cast, some abstain + // voting period on going + // over quorum (40% of 17 = 7, 17 casted_ + // 17 - 5 = 12 total opinions + // we need no votes > 0.4 * 12, no votes > 4.8 + // We can reject this even when it hasn't expired + assert!(check_is_rejected( + quorum.clone(), + rejected_ignoring_abstain, + 17, + false + )); + + // 3 votes uncast, if they all vote yes, we have 7 no, 7 yes+veto, 2 abstain (out of 16) + assert!(check_is_rejected(quorum, rejecting, 16, false)); + } + + #[test] + fn quorum_edge_cases() { + // when we pass absolute threshold (everyone else voting no, we pass), but still don't hit quorum + let quorum = Threshold::ThresholdQuorum { + threshold: Decimal::percent(60), + quorum: Decimal::percent(80), + }; + + // try 9 yes, 1 no (out of 15) -> 90% voter threshold, 60% absolute threshold, still no quorum + // doesn't matter if expired or not + let missing_voters = Votes { + yes: 9, + no: 1, + abstain: 0, + veto: 0, + }; + assert!(!check_is_passed( + quorum.clone(), + missing_voters.clone(), + 15, + false + )); + assert!(!check_is_passed(quorum.clone(), missing_voters, 15, true)); + + // 1 less yes, 3 vetos and this passes only when expired + let wait_til_expired = Votes { + yes: 8, + no: 1, + abstain: 0, + veto: 3, + }; + assert!(!check_is_passed( + quorum.clone(), + wait_til_expired.clone(), + 15, + false + )); + assert!(check_is_passed(quorum.clone(), wait_til_expired, 15, true)); + + // 9 yes and 3 nos passes early + let passes_early = Votes { + yes: 9, + no: 3, + abstain: 0, + veto: 0, + }; + assert!(check_is_passed( + quorum.clone(), + passes_early.clone(), + 15, + false + )); + assert!(check_is_passed(quorum, passes_early, 15, true)); + } +} diff --git a/packages/cw3/src/query.rs b/packages/cw3/src/query.rs index a20305489..3ba53f292 100644 --- a/packages/cw3/src/query.rs +++ b/packages/cw3/src/query.rs @@ -1,12 +1,8 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt; - use cosmwasm_schema::cw_serde; -use cosmwasm_std::{CosmosMsg, Empty}; +use cosmwasm_std::{Addr, CosmosMsg, Empty}; use cw_utils::{Expiration, ThresholdResponse}; -use crate::msg::Vote; +use crate::{msg::Vote, DepositInfo}; #[cw_serde] pub enum Cw3QueryMsg { @@ -53,24 +49,25 @@ pub enum Cw3QueryMsg { /// the querier needs to know what possible custom message types /// those are in order to parse the response #[cw_serde] -pub struct ProposalResponse -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ +pub struct ProposalResponse { pub id: u64, pub title: String, pub description: String, pub msgs: Vec>, pub status: Status, pub expires: Expiration, - /// This is the threshold that is applied to this proposal. Both the rules of the voting contract, - /// as well as the total_weight of the voting group may have changed since this time. That means - /// that the generic `Threshold{}` query does not provide valid information for existing proposals. + /// This is the threshold that is applied to this proposal. Both + /// the rules of the voting contract, as well as the total_weight + /// of the voting group may have changed since this time. That + /// means that the generic `Threshold{}` query does not provide + /// valid information for existing proposals. pub threshold: ThresholdResponse, + pub proposer: Addr, + pub deposit: Option, } -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "lowercase")] +#[cw_serde] +#[derive(Copy)] #[repr(u8)] pub enum Status { /// proposal was created, but voting has not yet begun for whatever reason @@ -86,10 +83,7 @@ pub enum Status { } #[cw_serde] -pub struct ProposalListResponse -where - T: Clone + fmt::Debug + PartialEq + JsonSchema, -{ +pub struct ProposalListResponse { pub proposals: Vec>, } From ae5b0020252234a836cd6728989d06f866c8e96c Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 1 Nov 2022 16:35:40 +0100 Subject: [PATCH 553/631] Add contributing guidelines --- .prettierrc.json | 10 ++++++ CONTRIBUTING.md | 11 ++++++ README.md | 93 +++++++++++++++++++++++++----------------------- 3 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 .prettierrc.json create mode 100644 CONTRIBUTING.md diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..6a82f4e8f --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "overrides": [ + { + "files": "*.md", + "options": { + "proseWrap": "always" + } + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..2967f9b5c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Contributing Guidelines + +We're happily accepting bugfixes, style improvements, good refactors and enhancements to documentation. + +For the specs, their APIs are considered final and immutable. We do not accept API-breaking changes. + +It is possible to propose a new protocol instead. In that case, please open an issue for discussion first, including +some motivating use cases. + +The contracts are not expected to be packed with features. They're expected to be minimal, reference implementations of +the specifications. We do not therefore accept enhancements. diff --git a/README.md b/README.md index 8d3fd6b68..7243eeaa4 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,20 @@ [![CircleCI](https://circleci.com/gh/CosmWasm/cw-plus/tree/main.svg?style=shield)](https://circleci.com/gh/CosmWasm/cw-plus/tree/main) -| Specification | Crates.io | Docs | Coverage | -|---------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| -| cw1 | [![cw1 on crates.io](https://img.shields.io/crates/v/cw1.svg)](https://crates.io/crates/cw1) | [![Docs](https://docs.rs/cw1/badge.svg)](https://docs.rs/cw1) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw2 | [![cw2 on crates.io](https://img.shields.io/crates/v/cw2.svg)](https://crates.io/crates/cw2) | [![Docs](https://docs.rs/cw2/badge.svg)](https://docs.rs/cw2) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | - -| Utilities | Crates.io | Docs | Coverage | -|-----------------|----------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| -| cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| Specification | Crates.io | Docs | Coverage | +| ------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| cw1 | [![cw1 on crates.io](https://img.shields.io/crates/v/cw1.svg)](https://crates.io/crates/cw1) | [![Docs](https://docs.rs/cw1/badge.svg)](https://docs.rs/cw1) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw2 | [![cw2 on crates.io](https://img.shields.io/crates/v/cw2.svg)](https://crates.io/crates/cw2) | [![Docs](https://docs.rs/cw2/badge.svg)](https://docs.rs/cw2) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +| cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | + +| Utilities | Crates.io | Docs | Coverage | +| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | + | Contracts | Download | Docs | Coverage | -|--------------------|----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | cw1-subkeys | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw1-whitelist | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_whitelist.wasm) | [![Docs](https://docs.rs/cw1-whitelist/badge.svg)](https://docs.rs/cw1-whitelist) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw3-fixed-multisig | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw3_fixed_multisig.wasm) | [![Docs](https://docs.rs/cw3-fixed-multisig/badge.svg)](https://docs.rs/cw3-fixed-multisig) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | @@ -57,7 +58,7 @@ The most reusable components are the various cwXYZ specifications under `packages`. Each one defines a standard interface for different domains, e.g. [cw20](./packages/cw20/README.md) for fungible tokens, [cw721](https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/README.md) for non-fungible tokens, -[cw1](./packages/cw1/README.md) for "proxy contracts", etc. +[cw1](./packages/cw1/README.md) for "proxy contracts", etc. The interface comes with a human description in the READMEs, as well as Rust types that can be imported. @@ -68,8 +69,7 @@ the real bonus of specifications, we can create an escrow contract that can handle many different fungible tokens, as long as they all adhere to the cw20 specification. -If you have ideas for new specifications or want to make enhancements to -existing spec, please [raise an issue](https://github.com/CosmWasm/cw-plus/issues) +If you have ideas for new specifications , please [raise an issue](https://github.com/CosmWasm/cw-plus/issues) or [create a pull request](https://github.com/CosmWasm/cw-plus/pulls) on this repo. ## Contracts @@ -84,42 +84,42 @@ contract you want to build on it. CW1 Proxy Contracts: -* [`cw1-whitelist`](./contracts/cw1-whitelist) a minimal implementation of `cw1` -mainly designed for reference. -* [`cw1-subkeys`](./contracts/cw1-subkeys) a simple, but useful implementation, -which lets us use a proxy contract to provide "allowances" for native tokens -without modifying the `bank` module. +- [`cw1-whitelist`](./contracts/cw1-whitelist) a minimal implementation of `cw1` + mainly designed for reference. +- [`cw1-subkeys`](./contracts/cw1-subkeys) a simple, but useful implementation, + which lets us use a proxy contract to provide "allowances" for native tokens + without modifying the `bank` module. CW3 Multisig: -* [`cw3-fixed-multisig`](./contracts/cw3-fixed-multisig) a simple implementation of the -[cw3 spec](./packages/cw3/README.md). It is a multisig with a fixed set of addresses, -created upon initialization. -Each address may have the same weight (K of N), or some may have extra voting -power. This works much like the native Cosmos SDK multisig, except that rather -than aggregating the signatures off chain and submitting the final result, -we aggregate the approvals on-chain. -* [`cw3-flex-multisig`](./contracts/cw3-flex-multisig) builds on cw3-fixed-multisig, -with a more powerful implementation of the cw3 spec. It's a multisig contract -backed by a cw4 (group) contract, which independently maintains the voter set. +- [`cw3-fixed-multisig`](./contracts/cw3-fixed-multisig) a simple implementation of the + [cw3 spec](./packages/cw3/README.md). It is a multisig with a fixed set of addresses, + created upon initialization. + Each address may have the same weight (K of N), or some may have extra voting + power. This works much like the native Cosmos SDK multisig, except that rather + than aggregating the signatures off chain and submitting the final result, + we aggregate the approvals on-chain. +- [`cw3-flex-multisig`](./contracts/cw3-flex-multisig) builds on cw3-fixed-multisig, + with a more powerful implementation of the cw3 spec. It's a multisig contract + backed by a cw4 (group) contract, which independently maintains the voter set. CW4 Group: -* [`cw4-group`](./contracts/cw4-group) a basic implementation of the -[cw4 spec](./packages/cw4/README.md). It handles elected membership, by admin or multisig. -It fulfills all elements of the spec, including raw query lookups, -and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). -* [`cw4-stake`](./contracts/cw4-stake) a second implementation of the -[cw4 spec](./packages/cw4/README.md). It fulfills all elements of the spec, including raw query lookups, -and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). -It provides a similar API to [`cw4-group`], but rather than appointing members, -their membership and weight are based on the number of staked tokens they have. +- [`cw4-group`](./contracts/cw4-group) a basic implementation of the + [cw4 spec](./packages/cw4/README.md). It handles elected membership, by admin or multisig. + It fulfills all elements of the spec, including raw query lookups, + and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). +- [`cw4-stake`](./contracts/cw4-stake) a second implementation of the + [cw4 spec](./packages/cw4/README.md). It fulfills all elements of the spec, including raw query lookups, + and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). + It provides a similar API to [`cw4-group`], but rather than appointing members, + their membership and weight are based on the number of staked tokens they have. CW20 Fungible Tokens: -* [`cw20-base`](./contracts/cw20-base) a straightforward, but complete -implementation of the cw20 spec along with all extensions. Can be deployed -as-is, or imported by other contracts. +- [`cw20-base`](./contracts/cw20-base) a straightforward, but complete + implementation of the cw20 spec along with all extensions. Can be deployed + as-is, or imported by other contracts. ## Compiling @@ -173,6 +173,10 @@ analyze this package, which gives much faster turn-around: Note that it will produce a code coverage report for the entire project, but only the coverage in that package is the real value. If does give quick feedback for you if you unit test writing was successful. +## Contributing + +See our [Contributing Guidelines](CONTRIBUTING.md). + ## Generating changelog To generate a changelog we decided to use [github-changelog-generator](https://github.com/github-changelog-generator/github-changelog-generator). @@ -202,7 +206,6 @@ auto-detect the latest version tag for you, with --latest-tag. This repo is licensed under [Apache 2.0](./LICENSE). -All *specifications* will always be Apache-2.0. All contracts that are -meant to be *building blocks* will also be Apache-2.0. This is along +All _specifications_ will always be Apache-2.0. All contracts that are +meant to be _building blocks_ will also be Apache-2.0. This is along the lines of Open Zeppelin or other public references. - From 850002c7116d3e6df6a1614d17e8aae69ce07b30 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 1 Nov 2022 16:45:47 +0100 Subject: [PATCH 554/631] Bump optimizer version in README --- README.md | 173 +++++++++++++++++++++++------------------------------- 1 file changed, 73 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 7243eeaa4..3007c2e2b 100644 --- a/README.md +++ b/README.md @@ -25,101 +25,80 @@ | cw20-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20-ics20 | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) -and can be followed there. +Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be +followed there. -Note: most of the `cw20-*` contracts besides `cw20-base` have moved to the new [`cw-tokens` repo](https://github.com/CosmWasm/cw-tokens) -and can be followed there. +Note: most of the `cw20-*` contracts besides `cw20-base` have moved to the new +[`cw-tokens` repo](https://github.com/CosmWasm/cw-tokens) and can be followed there. -This is a collection of specification and contracts designed for -use on real networks. They are designed not just as examples, but to -solve real-world use cases, and to provide a reusable basis to build -many custom contracts. +This is a collection of specification and contracts designed for use on real networks. They are designed not just as +examples, but to solve real-world use cases, and to provide a reusable basis to build many custom contracts. -If you don't know what CosmWasm is, please check out -[our homepage](https://cosmwasm.com) and -[our documentation](https://docs.cosmwasm.com) to get more background. -We are running [public testnets](https://github.com/CosmWasm/testnets#running) -you can use to test out any contracts. +If you don't know what CosmWasm is, please check out [our homepage](https://cosmwasm.com) and +[our documentation](https://docs.cosmwasm.com) to get more background. We are running +[public testnets](https://github.com/CosmWasm/testnets#running) you can use to test out any contracts. -**Warning** None of these contracts have been audited and no liability is -assumed for the use of this code. They are provided to turbo-start -your projects. +**Warning** None of these contracts have been audited and no liability is assumed for the use of this code. They are +provided to turbo-start your projects. -**Note** All code in pre-1.0 packages is in "draft" form, meaning it may -undergo minor changes and additions until 1.0. For example between 0.1 and -0.2 we adjusted the `Expiration` type to make the JSON representation -cleaner (before: `expires: {at_height: {height: 12345}}` after -`expires: {at_height: 12345}`) +**Note** All code in pre-1.0 packages is in "draft" form, meaning it may undergo minor changes and additions until 1.0. +For example between 0.1 and 0.2 we adjusted the `Expiration` type to make the JSON representation cleaner (before: +`expires: {at_height: {height: 12345}}` after `expires: {at_height: 12345}`) ## Specifications -The most reusable components are the various cwXYZ specifications under -`packages`. Each one defines a standard interface for different domains, -e.g. [cw20](./packages/cw20/README.md) for fungible tokens, +The most reusable components are the various cwXYZ specifications under `packages`. Each one defines a standard +interface for different domains, e.g. [cw20](./packages/cw20/README.md) for fungible tokens, [cw721](https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/README.md) for non-fungible tokens, -[cw1](./packages/cw1/README.md) for "proxy contracts", etc. -The interface comes with a human description in the READMEs, as well -as Rust types that can be imported. +[cw1](./packages/cw1/README.md) for "proxy contracts", etc. The interface comes with a human description in the READMEs, +as well as Rust types that can be imported. -They contain no logic, but specify an interface. It shows what you -need to implement to create a compatible contracts, as well as what -interface we guarantee to any consumer of such contracts. This is -the real bonus of specifications, we can create an escrow contract that -can handle many different fungible tokens, as long as they all adhere to -the cw20 specification. +They contain no logic, but specify an interface. It shows what you need to implement to create a compatible contracts, +as well as what interface we guarantee to any consumer of such contracts. This is the real bonus of specifications, we +can create an escrow contract that can handle many different fungible tokens, as long as they all adhere to the cw20 +specification. -If you have ideas for new specifications , please [raise an issue](https://github.com/CosmWasm/cw-plus/issues) -or [create a pull request](https://github.com/CosmWasm/cw-plus/pulls) on this repo. +If you have ideas for new specifications , please [raise an issue](https://github.com/CosmWasm/cw-plus/issues) or +[create a pull request](https://github.com/CosmWasm/cw-plus/pulls) on this repo. ## Contracts -We provide sample contracts that either implement or consume these -specifications to both provide examples, and provide a basis -for code you can extend for more custom contacts, without worrying -about reinventing the wheel each time. -For example [`cw20-base`](./contracts/cw20-base) is a basic implementation -of a `cw20` compatible contract that can be imported in any custom -contract you want to build on it. +We provide sample contracts that either implement or consume these specifications to both provide examples, and provide +a basis for code you can extend for more custom contacts, without worrying about reinventing the wheel each time. For +example [`cw20-base`](./contracts/cw20-base) is a basic implementation of a `cw20` compatible contract that can be +imported in any custom contract you want to build on it. CW1 Proxy Contracts: -- [`cw1-whitelist`](./contracts/cw1-whitelist) a minimal implementation of `cw1` - mainly designed for reference. -- [`cw1-subkeys`](./contracts/cw1-subkeys) a simple, but useful implementation, - which lets us use a proxy contract to provide "allowances" for native tokens - without modifying the `bank` module. +- [`cw1-whitelist`](./contracts/cw1-whitelist) a minimal implementation of `cw1` mainly designed for reference. +- [`cw1-subkeys`](./contracts/cw1-subkeys) a simple, but useful implementation, which lets us use a proxy contract to + provide "allowances" for native tokens without modifying the `bank` module. CW3 Multisig: - [`cw3-fixed-multisig`](./contracts/cw3-fixed-multisig) a simple implementation of the - [cw3 spec](./packages/cw3/README.md). It is a multisig with a fixed set of addresses, - created upon initialization. - Each address may have the same weight (K of N), or some may have extra voting - power. This works much like the native Cosmos SDK multisig, except that rather - than aggregating the signatures off chain and submitting the final result, - we aggregate the approvals on-chain. -- [`cw3-flex-multisig`](./contracts/cw3-flex-multisig) builds on cw3-fixed-multisig, - with a more powerful implementation of the cw3 spec. It's a multisig contract - backed by a cw4 (group) contract, which independently maintains the voter set. + [cw3 spec](./packages/cw3/README.md). It is a multisig with a fixed set of addresses, created upon initialization. + Each address may have the same weight (K of N), or some may have extra voting power. This works much like the native + Cosmos SDK multisig, except that rather than aggregating the signatures off chain and submitting the final result, we + aggregate the approvals on-chain. +- [`cw3-flex-multisig`](./contracts/cw3-flex-multisig) builds on cw3-fixed-multisig, with a more powerful implementation + of the cw3 spec. It's a multisig contract backed by a cw4 (group) contract, which independently maintains the voter + set. CW4 Group: -- [`cw4-group`](./contracts/cw4-group) a basic implementation of the - [cw4 spec](./packages/cw4/README.md). It handles elected membership, by admin or multisig. - It fulfills all elements of the spec, including raw query lookups, - and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). -- [`cw4-stake`](./contracts/cw4-stake) a second implementation of the - [cw4 spec](./packages/cw4/README.md). It fulfills all elements of the spec, including raw query lookups, - and is designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). - It provides a similar API to [`cw4-group`], but rather than appointing members, - their membership and weight are based on the number of staked tokens they have. +- [`cw4-group`](./contracts/cw4-group) a basic implementation of the [cw4 spec](./packages/cw4/README.md). It handles + elected membership, by admin or multisig. It fulfills all elements of the spec, including raw query lookups, and is + designed to be used as a backing storage for [cw3 compliant contracts](./packages/cw3/README.md). +- [`cw4-stake`](./contracts/cw4-stake) a second implementation of the [cw4 spec](./packages/cw4/README.md). It fulfills + all elements of the spec, including raw query lookups, and is designed to be used as a backing storage for + [cw3 compliant contracts](./packages/cw3/README.md). It provides a similar API to [`cw4-group`], but rather than + appointing members, their membership and weight are based on the number of staked tokens they have. CW20 Fungible Tokens: -- [`cw20-base`](./contracts/cw20-base) a straightforward, but complete - implementation of the cw20 spec along with all extensions. Can be deployed - as-is, or imported by other contracts. +- [`cw20-base`](./contracts/cw20-base) a straightforward, but complete implementation of the cw20 spec along with all + extensions. Can be deployed as-is, or imported by other contracts. ## Compiling @@ -129,32 +108,27 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.6 + cosmwasm/workspace-optimizer:0.12.8 ``` -This will compile all packages in the `contracts` directory and output the -stripped and optimized wasm code under the `artifacts` directory as output, -along with a `checksums.txt` file. +This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the +`artifacts` directory as output, along with a `checksums.txt` file. -If you hit any issues there and want to debug, you can try to run the -following in each contract dir: +If you hit any issues there and want to debug, you can try to run the following in each contract dir: `RUSTFLAGS="-C link-arg=-s" cargo build --release --target=wasm32-unknown-unknown --locked` ## Quality Control -One of the basic metrics of assurance over code quality is how much is covered by -unit tests. There are several tools available for Rust to do such analysis and -we will describe one below. This should be used as a baseline metric to give some -confidence in the code. +One of the basic metrics of assurance over code quality is how much is covered by unit tests. There are several tools +available for Rust to do such analysis and we will describe one below. This should be used as a baseline metric to give +some confidence in the code. -Beyond code coverage metrics, just having a robust PR review process with a few -more trained eyes looking for bugs is very helpful in detecting paths the original -coder was not aware of. This is more subjective, but looking at the relevant PRs -and depth of discussion can give an idea how much review was present. +Beyond code coverage metrics, just having a robust PR review process with a few more trained eyes looking for bugs is +very helpful in detecting paths the original coder was not aware of. This is more subjective, but looking at the +relevant PRs and depth of discussion can give an idea how much review was present. -After that, fuzzing it (ideally with an intelligent fuzzer that understands the domain) -can be valuable. And beyond that formal verification can provide even more assurance -(but is very time-consuming and expensive). +After that, fuzzing it (ideally with an intelligent fuzzer that understands the domain) can be valuable. And beyond that +formal verification can provide even more assurance (but is very time-consuming and expensive). ### Code Coverage @@ -162,16 +136,15 @@ I recommend the use of [tarpaulin](https://github.com/xd009642/tarpaulin): `carg To get some nice interactive charts, you can go to the root directory and run: -`cargo tarpaulin -o html` -and then `xdg-open tarpaulin-report.html` (or just `open` on MacOS). +`cargo tarpaulin -o html` and then `xdg-open tarpaulin-report.html` (or just `open` on MacOS). -Once you find a package that you want to improve, you can do the following to just -analyze this package, which gives much faster turn-around: +Once you find a package that you want to improve, you can do the following to just analyze this package, which gives +much faster turn-around: `cargo tarpaulin -o html --packages cw3-fixed-multisig` -Note that it will produce a code coverage report for the entire project, but only the coverage in that -package is the real value. If does give quick feedback for you if you unit test writing was successful. +Note that it will produce a code coverage report for the entire project, but only the coverage in that package is the +real value. If does give quick feedback for you if you unit test writing was successful. ## Contributing @@ -179,7 +152,8 @@ See our [Contributing Guidelines](CONTRIBUTING.md). ## Generating changelog -To generate a changelog we decided to use [github-changelog-generator](https://github.com/github-changelog-generator/github-changelog-generator). +To generate a changelog we decided to use +[github-changelog-generator](https://github.com/github-changelog-generator/github-changelog-generator). To install tool you need Ruby's `gem` package manager. @@ -195,17 +169,16 @@ Appending next releases could be done adding `--base` flag: $ github_changelog_generator -u CosmWasm -p cw-plus --base CHANGELOG.md -If you hit GitHub's 50 requests/hour limit, please follow [this](https://github.com/github-changelog-generator/github-changelog-generator#github-token) -guide to create a token key which you can pass using `--token` flag. +If you hit GitHub's 50 requests/hour limit, please follow +[this](https://github.com/github-changelog-generator/github-changelog-generator#github-token) guide to create a token +key which you can pass using `--token` flag. -There's also a convenience `scripts/update_changelog.sh`, which can take a ---since-tag parameter (to avoid processing the entire history). It can also -auto-detect the latest version tag for you, with --latest-tag. +There's also a convenience `scripts/update_changelog.sh`, which can take a --since-tag parameter (to avoid processing +the entire history). It can also auto-detect the latest version tag for you, with --latest-tag. ## Licenses This repo is licensed under [Apache 2.0](./LICENSE). -All _specifications_ will always be Apache-2.0. All contracts that are -meant to be _building blocks_ will also be Apache-2.0. This is along -the lines of Open Zeppelin or other public references. +All _specifications_ will always be Apache-2.0. All contracts that are meant to be _building blocks_ will also be +Apache-2.0. This is along the lines of Open Zeppelin or other public references. From f088e1b184d236ce252116673803a1fee055969c Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 9 Nov 2022 13:44:32 +0100 Subject: [PATCH 555/631] README update --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 3007c2e2b..ae6b28e80 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,6 @@ If you don't know what CosmWasm is, please check out [our homepage](https://cosm **Warning** None of these contracts have been audited and no liability is assumed for the use of this code. They are provided to turbo-start your projects. -**Note** All code in pre-1.0 packages is in "draft" form, meaning it may undergo minor changes and additions until 1.0. -For example between 0.1 and 0.2 we adjusted the `Expiration` type to make the JSON representation cleaner (before: -`expires: {at_height: {height: 12345}}` after `expires: {at_height: 12345}`) - ## Specifications The most reusable components are the various cwXYZ specifications under `packages`. Each one defines a standard @@ -108,7 +104,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.8 + cosmwasm/workspace-optimizer:0.12.9 ``` This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the From 648ec1317d1f4f498853cf7881bbb37b34da0e4a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 23 Nov 2022 17:14:17 +0100 Subject: [PATCH 556/631] Standardize spec events --- packages/cw1/README.md | 41 +++--- packages/cw20/README.md | 312 ++++++++++++++++++++++++---------------- packages/cw3/README.md | 203 +++++++++++++------------- packages/cw4/README.md | 149 +++++++++---------- 4 files changed, 382 insertions(+), 323 deletions(-) diff --git a/packages/cw1/README.md b/packages/cw1/README.md index 72a95915a..77ed3c25a 100644 --- a/packages/cw1/README.md +++ b/packages/cw1/README.md @@ -1,33 +1,30 @@ # CW1 Spec: Proxy Contracts -CW1 is a specification for proxy contracts based on CosmWasm. -It is a very simple, but flexible interface designed for the case -where one contract is meant to hold assets (or rights) on behalf of -other contracts. +CW1 is a specification for proxy contracts based on CosmWasm. It is a very simple, but flexible interface designed for +the case where one contract is meant to hold assets (or rights) on behalf of other contracts. -The simplest example is a contract that will accept messages from -the creator and resend them from its address. Simply by making this -transferable, you can then begin to transfer non-transferable assets -(eg. staked tokens, voting power, etc). +The simplest example is a contract that will accept messages from the creator and resend them from its address. Simply +by making this transferable, you can then begin to transfer non-transferable assets (eg. staked tokens, voting power, +etc). -You can imagine more complex examples, such as a "1 of N" multisig, -or conditional approval, where "sub-accounts" have the right to spend -a limited amount of funds from this account, with a "admin account" -retaining full control. +You can imagine more complex examples, such as a "1 of N" multisig, or conditional approval, where "sub-accounts" have +the right to spend a limited amount of funds from this account, with a "admin account" retaining full control. -The common denominator is that they allow you to immediately -execute arbitrary `CosmosMsg` in the same transaction. +The common denominator is that they allow you to immediately execute arbitrary `CosmosMsg` in the same transaction. ### Messages -`Execute{msgs}` - This accepts `Vec` and checks permissions -before re-dispatching all those messages from the contract address. +`Execute{msgs}` - This accepts `Vec` and checks permissions before re-dispatching all those messages from the +contract address. It emits the following attributes: + +| Key | Value | +| -------- | ------------ | +| "action" | "execute" | +| "owner" | [msg sender] | ### Queries -`CanExecute{sender, msg}` - This accepts one `CosmosMsg` and checks permissions, -returning true or false based on the permissions. If `CanExecute` returns true -then a call to `Execute` from that sender, with the same message, -before any further state changes, should also succeed. This can be used -to dynamically provide some client info on a generic cw1 contract without -knowing the extension details. (eg. detect if they can send coins or stake) +`CanExecute{sender, msg}` - This accepts one `CosmosMsg` and checks permissions, returning true or false based on the +permissions. If `CanExecute` returns true then a call to `Execute` from that sender, with the same message, before any +further state changes, should also succeed. This can be used to dynamically provide some client info on a generic cw1 +contract without knowing the extension details. (eg. detect if they can send coins or stake) diff --git a/packages/cw20/README.md b/packages/cw20/README.md index c09cec75b..8eb118445 100644 --- a/packages/cw20/README.md +++ b/packages/cw20/README.md @@ -1,188 +1,256 @@ # CW20 Spec: Fungible Tokens -CW20 is a specification for fungible tokens based on CosmWasm. -The name and design is loosely based on Ethereum's ERC20 standard, -but many changes have been made. The types in here can be imported by -contracts that wish to implement this spec, or by contracts that call -to any standard cw20 contract. +CW20 is a specification for fungible tokens based on CosmWasm. The name and design is loosely based on Ethereum's ERC20 +standard, but many changes have been made. The types in here can be imported by contracts that wish to implement this +spec, or by contracts that call to any standard cw20 contract. -The specification is split into multiple sections, a contract may only -implement some of this functionality, but must implement the base. +The specification is split into multiple sections, a contract may only implement some of this functionality, but must +implement the base. ## Base -This handles balances and transfers. Note that all amounts are -handled as `Uint128` (128 bit integers with JSON string representation). -Handling decimals is left to the UI and not interpreted +This handles balances and transfers. Note that all amounts are handled as `Uint128` (128 bit integers with JSON string +representation). Handling decimals is left to the UI and not interpreted ### Messages -`Transfer{recipient, amount}` - Moves `amount` tokens from the -`info.sender` account to the `recipient` account. This is designed to -send to an address controlled by a private key and *does not* trigger -any actions on the recipient if it is a contract. +`Transfer{recipient, amount}` - Moves `amount` tokens from the `info.sender` account to the `recipient` account. This is +designed to send to an address controlled by a private key and _does not_ trigger any actions on the recipient if it is +a contract. -`Send{contract, amount, msg}` - Moves `amount` tokens from the -`info.sender` account to the `contract` account. `contract` must be an -address of a contract that implements the `Receiver` interface. The `msg` -will be passed to the recipient contract, along with the amount. +Attributes emitted: -`Burn{amount}` - Remove `amount` tokens from the balance of `info.sender` -and reduce `total_supply` by the same amount. +| Key | Value | +| -------- | ---------- | +| "action" | "transfer" | +| "from" | sender | +| "to" | recipient | +| "amount" | amount | + +`Send{contract, amount, msg}` - Moves `amount` tokens from the `info.sender` account to the `contract` account. +`contract` must be an address of a contract that implements the `Receiver` interface. The `msg` will be passed to the +recipient contract, along with the amount. + +Attributes emitted: + +| Key | Value | +| -------- | --------- | +| "action" | "send" | +| "from" | sender | +| "to" | recipient | +| "amount" | amount | + +`Burn{amount}` - Remove `amount` tokens from the balance of `info.sender` and reduce `total_supply` by the same amount. + +Attributes emitted: + +| Key | Value | +| -------- | ------ | +| "action" | "burn" | +| "from" | sender | +| "amount" | amount | ### Queries -`Balance{address}` - Returns the balance of the given address. -Returns "0" if the address is unknown to the contract. Return type -is `BalanceResponse{balance}`. +`Balance{address}` - Returns the balance of the given address. Returns "0" if the address is unknown to the contract. +Return type is `BalanceResponse{balance}`. `TokenInfo{}` - Returns the token info of the contract. Return type is `TokenInfoResponse{name, symbol, decimal, total_supply}`. ### Receiver -The counter-part to `Send` is `Receive`, which must be implemented by -any contract that wishes to manage CW20 tokens. This is generally *not* -implemented by any CW20 contract. +The counter-part to `Send` is `Receive`, which must be implemented by any contract that wishes to manage CW20 tokens. +This is generally _not_ implemented by any CW20 contract. -`Receive{sender, amount, msg}` - This is designed to handle `Send` -messages. The address of the contract is stored in `info.sender` -so it cannot be faked. The contract should ensure the sender matches -the token contract it expects to handle, and not allow arbitrary addresses. +`Receive{sender, amount, msg}` - This is designed to handle `Send` messages. The address of the contract is stored in +`info.sender` so it cannot be faked. The contract should ensure the sender matches the token contract it expects to +handle, and not allow arbitrary addresses. -The `sender` is the original account requesting to move the tokens -and `msg` is a `Binary` data that can be decoded into a contract-specific -message. This can be empty if we have only one default action, -or it may be a `ReceiveMsg` variant to clarify the intention. For example, -if I send to a uniswap contract, I can specify which token I want to swap -against using this field. +The `sender` is the original account requesting to move the tokens and `msg` is a `Binary` data that can be decoded into +a contract-specific message. This can be empty if we have only one default action, or it may be a `ReceiveMsg` variant +to clarify the intention. For example, if I send to a uniswap contract, I can specify which token I want to swap against +using this field. ## Allowances -A contract may allow actors to delegate some of their balance to other -accounts. This is not as essential as with ERC20 as we use `Send`/`Receive` -to send tokens to a contract, not `Approve`/`TransferFrom`. But it -is still a nice use-case, and you can see how the Cosmos SDK wants to add -payment allowances to native tokens. This is mainly designed to provide +A contract may allow actors to delegate some of their balance to other accounts. This is not as essential as with ERC20 +as we use `Send`/`Receive` to send tokens to a contract, not `Approve`/`TransferFrom`. But it is still a nice use-case, +and you can see how the Cosmos SDK wants to add payment allowances to native tokens. This is mainly designed to provide access to other public-key-based accounts. -There was an issue with race conditions in the original ERC20 approval spec. -If you had an approval of 50 and I then want to reduce it to 20, I submit a -Tx to set the allowance to 20. If you see that and immediately submit a tx -using the entire 50, you then get access to the other 20. Not only did you quickly -spend the 50 before I could reduce it, you get another 20 for free. +There was an issue with race conditions in the original ERC20 approval spec. If you had an approval of 50 and I then +want to reduce it to 20, I submit a Tx to set the allowance to 20. If you see that and immediately submit a tx using the +entire 50, you then get access to the other 20. Not only did you quickly spend the 50 before I could reduce it, you get +another 20 for free. -The solution discussed in the Ethereum community was an `IncreaseAllowance` -and `DecreaseAllowance` operator (instead of `Approve`). To originally set -an approval, use `IncreaseAllowance`, which works fine with no previous allowance. -`DecreaseAllowance` is meant to be robust, that is if you decrease by more than -the current allowance (eg. the user spent some in the middle), it will just round -down to 0 and not make any underflow error. +The solution discussed in the Ethereum community was an `IncreaseAllowance` and `DecreaseAllowance` operator (instead of +`Approve`). To originally set an approval, use `IncreaseAllowance`, which works fine with no previous allowance. +`DecreaseAllowance` is meant to be robust, that is if you decrease by more than the current allowance (eg. the user +spent some in the middle), it will just round down to 0 and not make any underflow error. ### Messages -`IncreaseAllowance{spender, amount, expires}` - Set or increase the allowance -such that `spender` may access up to `amount + current_allowance` tokens -from the `info.sender` account. This may optionally come with an `Expiration` -time, which if set limits when the approval can be used (by time or height). - -`DecreaseAllowance{spender, amount, expires}` - Decrease or clear the allowance -such that `spender` may access up to `current_allowance - amount` tokens -from the `info.sender` account. This may optionally come with an `Expiration` -time, which if set limits when the approval can be used (by time or height). -If `amount >= current_allowance`, this will clear the allowance (delete it). - -`TransferFrom{owner, recipient, amount}` - This makes use of an allowance -and if there was a valid, un-expired pre-approval for the `info.sender`, -then we move `amount` tokens from `owner` to `recipient` and deduct it -from the available allowance. - -`SendFrom{owner, contract, amount, msg}` - `SendFrom` is to `Send`, what -`TransferFrom` is to `Transfer`. This allows a pre-approved account to -not just transfer the tokens, but to send them to another contract -to trigger a given action. **Note** `SendFrom` will set the `Receive{sender}` -to be the `info.sender` (the account that triggered the transfer) -rather than the `owner` account (the account the money is coming from). -This is an open question whether we should switch this? - -`BurnFrom{owner, amount}` - This works like `TransferFrom`, but burns -the tokens instead of transfering them. This will reduce the owner's -balance, `total_supply` and the caller's allowance. +`IncreaseAllowance{spender, amount, expires}` - Set or increase the allowance such that `spender` may access up to +`amount + current_allowance` tokens from the `info.sender` account. This may optionally come with an `Expiration` time, +which if set limits when the approval can be used (by time or height). + +Attributes emitted: + +| Key | Value | +| --------- | -------------------- | +| "action" | "increase_allowance" | +| "owner" | sender | +| "spender" | spender | +| "amount" | amount | + +`DecreaseAllowance{spender, amount, expires}` - Decrease or clear the allowance such that `spender` may access up to +`current_allowance - amount` tokens from the `info.sender` account. This may optionally come with an `Expiration` time, +which if set limits when the approval can be used (by time or height). If `amount >= current_allowance`, this will clear +the allowance (delete it). + +Attributes emitted: + +| Key | Value | +| --------- | -------------------- | +| "action" | "decrease_allowance" | +| "owner" | sender | +| "spender" | spender | +| "amount" | amount | + +`TransferFrom{owner, recipient, amount}` - This makes use of an allowance and if there was a valid, un-expired +pre-approval for the `info.sender`, then we move `amount` tokens from `owner` to `recipient` and deduct it from the +available allowance. + +Attributes emitted: + +| Key | Value | +| -------- | ------------------------ | +| "action" | "transfer_from" | +| "from" | account transferred from | +| "to" | recipient | +| "by" | message sender | +| "amount" | amount | + +`SendFrom{owner, contract, amount, msg}` - `SendFrom` is to `Send`, what `TransferFrom` is to `Transfer`. This allows a +pre-approved account to not just transfer the tokens, but to send them to another contract to trigger a given action. +**Note** `SendFrom` will set the `Receive{sender}` to be the `info.sender` (the account that triggered the transfer) +rather than the `owner` account (the account the money is coming from). This is an open question whether we should +switch this? + +Attributes emitted: + +| Key | Value | +| -------- | ----------------- | +| "action" | "send_from" | +| "from" | account sent from | +| "to" | recipient | +| "by" | message sender | +| "amount" | amount | + +`BurnFrom{owner, amount}` - This works like `TransferFrom`, but burns the tokens instead of transfering them. This will +reduce the owner's balance, `total_supply` and the caller's allowance. + +Attributes emitted: + +| Key | Value | +| -------- | ------------------ | +| "action" | "burn_from" | +| "from" | account burnt from | +| "by" | message sender | +| "amount" | amount | ### Queries -`Allowance{owner, spender}` - This returns the available allowance -that `spender` can access from the `owner`'s account, along with the -expiration info. Return type is `AllowanceResponse{balance, expiration}`. +`Allowance{owner, spender}` - This returns the available allowance that `spender` can access from the `owner`'s account, +along with the expiration info. Return type is `AllowanceResponse{balance, expiration}`. ## Mintable -This allows another contract to mint new tokens, possibly with a cap. -There is only one minter specified here, if you want more complex -access management, please use a multisig or other contract as the -minter address and handle updating the ACL there. +This allows another contract to mint new tokens, possibly with a cap. There is only one minter specified here, if you +want more complex access management, please use a multisig or other contract as the minter address and handle updating +the ACL there. ### Messages -`Mint{recipient, amount}` - If the `info.sender` is the allowed minter, -this will create `amount` new tokens (updating total supply) and -add them to the balance of `recipient`, as long as it does not exceed the cap. +`Mint{recipient, amount}` - If the `info.sender` is the allowed minter, this will create `amount` new tokens (updating +total supply) and add them to the balance of `recipient`, as long as it does not exceed the cap. + +Attributes emitted: -`UpdateMinter { new_minter: Option }` - Callable only by the -current minter. If `new_minter` is `Some(address)` the minter is set -to the specified address, otherwise the minter is removed and no -future minters may be set. +| Key | Value | +| -------- | --------- | +| "action" | "mint" | +| "to" | recipient | +| "amount" | amount | + +`UpdateMinter { new_minter: Option }` - Callable only by the current minter. If `new_minter` is `Some(address)` +the minter is set to the specified address, otherwise the minter is removed and no future minters may be set. + +Attributes emitted: + +| Key | Value | +| ------------ | ----------------------------------- | +| "action" | "update_minter" | +| "new_minter" | minter address or "None" if removed | ### Queries -`Minter{}` - Returns who and how much can be minted. Return type is -`MinterResponse {minter, cap}`. Cap may be unset. +`Minter{}` - Returns who and how much can be minted. Return type is `MinterResponse {minter, cap}`. Cap may be unset. -If the cap is set, it defines the maximum `total_supply` that may ever exist. -If initial supply is 1000 and cap is `Some(2000)`, you can only mint 1000 more tokens. -However, if someone then burns 500 tokens, the minter can mint those 500 again. -This allows for dynamic token supply within a set of parameters, especially when -the minter is a smart contract. +If the cap is set, it defines the maximum `total_supply` that may ever exist. If initial supply is 1000 and cap is +`Some(2000)`, you can only mint 1000 more tokens. However, if someone then burns 500 tokens, the minter can mint those +500 again. This allows for dynamic token supply within a set of parameters, especially when the minter is a smart +contract. ## Enumerable -This should be enabled with all blockchains that have iterator support. -It allows us to get lists of results with pagination. +This should be enabled with all blockchains that have iterator support. It allows us to get lists of results with +pagination. ### Queries -`AllAllowances{owner, start_after, limit}` - Returns the list of all non-expired allowances -by the given owner. `start_after` and `limit` provide pagination. +`AllAllowances{owner, start_after, limit}` - Returns the list of all non-expired allowances by the given owner. +`start_after` and `limit` provide pagination. -`AllAccounts{start_after, limit}` - Returns the list of all accounts that have been created on -the contract (just the addresses). `start_after` and `limit` provide pagination. +`AllAccounts{start_after, limit}` - Returns the list of all accounts that have been created on the contract (just the +addresses). `start_after` and `limit` provide pagination. ## Marketing -This allows us to attach more metadata on the token to help with displaying the token in -wallets. When you see a token's website, then see it in a wallet, you know what it is. -However, if you see it in a wallet or a DEX trading pair, there is no clear way to find out -any more info about it. +This allows us to attach more metadata on the token to help with displaying the token in wallets. When you see a token's +website, then see it in a wallet, you know what it is. However, if you see it in a wallet or a DEX trading pair, there +is no clear way to find out any more info about it. -This extension allows us to attach more "Marketing" metadata, which has no effect on the -on-chain functionality of the token, but is very useful in providing a better client-side -experience. Note, that we add a new role `marketing`, which can update such info, but not -affect on-chain logic. +This extension allows us to attach more "Marketing" metadata, which has no effect on the on-chain functionality of the +token, but is very useful in providing a better client-side experience. Note, that we add a new role `marketing`, which +can update such info, but not affect on-chain logic. ### Messages -`UploadLogo{url | embedded}` - If the `info.sender` is the allowed marketing account, -this will either set a new URL reference where the logo is served, or allow them to upload -a small (less than 5KB) SVG or PNG logo onto the blockchain to be served. +`UploadLogo{url | embedded}` - If the `info.sender` is the allowed marketing account, this will either set a new URL +reference where the logo is served, or allow them to upload a small (less than 5KB) SVG or PNG logo onto the blockchain +to be served. + +Attributes emitted: + +| Key | Value | +| -------- | ------------- | +| "action" | "upload_logo" | + +`UpdateMarketing{project, description, marketing}` - If the `info.sender` is the allowed marketing account, this will +update some marketing-related metadata on the contract. + +Attributes emitted: -`UpdateMarketing{project, description, marketing}` - If the `info.sender` is the allowed marketing -account, this will update some marketing-related metadata on the contract. +| Key | Value | +| -------- | ------------------ | +| "action" | "update_marketing" | ### Queries `MarketingInfo{}` - Returns marketing-related metadata. Return type is `MarketingInfoResponse {project, description, logo, marketing}`. -`DownloadLogo{}` - If the token's logo was previously uploaded to the blockchain -(see `UploadLogo` message), then it returns the raw data to be displayed in a browser. -Return type is `DownloadLogoResponse{ mime_type, data }`. +`DownloadLogo{}` - If the token's logo was previously uploaded to the blockchain (see `UploadLogo` message), then it +returns the raw data to be displayed in a browser. Return type is `DownloadLogoResponse{ mime_type, data }`. diff --git a/packages/cw3/README.md b/packages/cw3/README.md index dccb35b8e..7f4cfe95b 100644 --- a/packages/cw3/README.md +++ b/packages/cw3/README.md @@ -1,131 +1,122 @@ # CW3 Spec: MultiSig/Voting Contracts -CW3 is a specification for voting contracts based on CosmWasm. -It is an extension of CW1 (which served as an immediate 1 of N multisig). -In this case, no key can immediately execute, but only propose -a set of messages for execution. The proposal, subsequent -approvals, and signature aggregation all happen on chain. +CW3 is a specification for voting contracts based on CosmWasm. It is an extension of CW1 (which served as an immediate 1 +of N multisig). In this case, no key can immediately execute, but only propose a set of messages for execution. The +proposal, subsequent approvals, and signature aggregation all happen on chain. There are at least 3 different cases we want to cover in this spec: -- K of N immutible multisig. One key proposes a set of messages, - after K-1 others approve it, it can be executed with the - multisig address. -- K of N flexible, mutable multisig. Like above, but with - multiple contracts. One contract stores the group, which is - referenced from multiple multisig contracts (which in turn - implement cw3). One cw3 contracts is able to update the - group content (maybe needing 67% vote). Other cw3 contracts - may hold tokens, staking rights, etc with various execution - thresholds, all controlled by one group. (Group interface - and updating them will be defined in a future spec, likely cw4). - -This should fit in this interface (possibly with some -extensions for pieces, but the usage should look the -same externally): - -- Token weighted voting. People lock tokens in a contract - for voting rights. There is a vote threshold to execute - messages. The voting set is dynamic. This has a similar - "propose, approve, execute" flow, but we will need to - support clear YES/NO votes and quora not just absolute - thresholds. - -The common denominator is that they allow you to propose -arbitrary `CosmosMsg` to a contract, and allow a series -of votes/approvals to determine if it can be executed, -as well as a final step to execute any approved proposal once. +- K of N immutible multisig. One key proposes a set of messages, after K-1 others approve it, it can be executed with + the multisig address. +- K of N flexible, mutable multisig. Like above, but with multiple contracts. One contract stores the group, which is + referenced from multiple multisig contracts (which in turn implement cw3). One cw3 contracts is able to update the + group content (maybe needing 67% vote). Other cw3 contracts may hold tokens, staking rights, etc with various + execution thresholds, all controlled by one group. (Group interface and updating them will be defined in a future + spec, likely cw4). + +This should fit in this interface (possibly with some extensions for pieces, but the usage should look the same +externally): + +- Token weighted voting. People lock tokens in a contract for voting rights. There is a vote threshold to execute + messages. The voting set is dynamic. This has a similar "propose, approve, execute" flow, but we will need to support + clear YES/NO votes and quora not just absolute thresholds. + +The common denominator is that they allow you to propose arbitrary `CosmosMsg` to a contract, and allow a series of +votes/approvals to determine if it can be executed, as well as a final step to execute any approved proposal once. ## Base -The following interfaces must be implemented for all cw3 -contracts. Note that updating the members of the voting -contract is not contained here (one approach is defined in cw4). -Also, how to change the threshold rules (if at all) is not -standardized. Those are considered admin tasks, and the common -API is designed for standard usage, as that is where we can -standardize the most tooling without limiting more complex -governance controls. +The following interfaces must be implemented for all cw3 contracts. Note that updating the members of the voting +contract is not contained here (one approach is defined in cw4). Also, how to change the threshold rules (if at all) is +not standardized. Those are considered admin tasks, and the common API is designed for standard usage, as that is where +we can standardize the most tooling without limiting more complex governance controls. ### Messages -`Propose{title, description, msgs, earliest, latest}` - This accepts -`Vec` and creates a new proposal. This will return -an auto-generated ID in the `Data` field (and the logs) that -can be used to reference the proposal later. - -If the Proposer is a valid voter on the proposal, this will imply a Yes vote by -the Proposer for a faster workflow, especially useful in eg. 2 of 3 -or 3 of 5 multisig, we don't need to propose in one block, get result, -and vote in another block. - -Earliest and latest are optional and can request the first -and last height/time that we can try `Execute`. For a vote, -we may require at least 2 days to pass, but no more than 7. -This is optional and even if set, may be modified by the contract -(overriding or just enforcing min/max/default values). - -Many implementations will want to restrict who can propose. -Maybe only people in the voting set. Maybe there is some -deposit to be made along with the proposal. This is not -in the spec but left open to the implementation. - -`Vote{proposal_id, vote}` - Given a proposal_id, you can -vote yes, no, abstain or veto. Each signed may have a -different "weight" in the voting and they apply their -entire weight on the vote. - -Many contracts (like typical -multisig with absolute threshold) may consider veto and -abstain as no and just count yes votes. Contracts with quora -may count abstain towards quora but not yes or no for threshold. -Some contracts may give extra power to veto rather than a -simple no, but this may just act like a normal no vote. - -`Execute{proposal_id}` - This will check if the voting -conditions have passed for the given proposal. If it has -succeeded, the proposal is marked as `Executed` and the -messages are dispatched. If the messages fail (eg out of gas), -this is all reverted and can be tried again later with -more gas. - -`Close{proposal_id}` - This will check if the voting conditions -have failed for the given proposal. If so (eg. time expired -and insufficient votes), then the proposal is marked `Failed`. -This is not strictly necessary, as it will only act when -it is impossible the contract would ever be executed, -but can be triggered to provide some better UI. +`Propose{title, description, msgs, earliest, latest}` - This accepts `Vec` and creates a new proposal. This +will return an auto-generated ID in the `Data` field (and the logs) that can be used to reference the proposal later. + +If the Proposer is a valid voter on the proposal, this will imply a Yes vote by the Proposer for a faster workflow, +especially useful in eg. 2 of 3 or 3 of 5 multisig, we don't need to propose in one block, get result, and vote in +another block. + +Earliest and latest are optional and can request the first and last height/time that we can try `Execute`. For a vote, +we may require at least 2 days to pass, but no more than 7. This is optional and even if set, may be modified by the +contract (overriding or just enforcing min/max/default values). + +Many implementations will want to restrict who can propose. Maybe only people in the voting set. Maybe there is some +deposit to be made along with the proposal. This is not in the spec but left open to the implementation. + +Attributes emitted: + +| Key | Value | +| ------------- | ---------------------- | +| "action" | "propose" | +| "sender" | msg sender | +| "proposal_id" | a UID for the proposal | +| "status" | new proposal status | + +`Vote{proposal_id, vote}` - Given a proposal_id, you can vote yes, no, abstain or veto. Each signed may have a different +"weight" in the voting and they apply their entire weight on the vote. + +Many contracts (like typical multisig with absolute threshold) may consider veto and abstain as no and just count yes +votes. Contracts with quora may count abstain towards quora but not yes or no for threshold. Some contracts may give +extra power to veto rather than a simple no, but this may just act like a normal no vote. + +Attributes emitted: + +| Key | Value | +| ------------- | ---------------------- | +| "action" | "vote" | +| "sender" | msg sender | +| "proposal_id" | a UID for the proposal | +| "status" | new proposal status | + +`Execute{proposal_id}` - This will check if the voting conditions have passed for the given proposal. If it has +succeeded, the proposal is marked as `Executed` and the messages are dispatched. If the messages fail (eg out of gas), +this is all reverted and can be tried again later with more gas. + +Attributes emitted: + +| Key | Value | +| ------------- | ---------------------- | +| "action" | "execute" | +| "sender" | msg sender | +| "proposal_id" | a UID for the proposal | + +`Close{proposal_id}` - This will check if the voting conditions have failed for the given proposal. If so (eg. time +expired and insufficient votes), then the proposal is marked `Failed`. This is not strictly necessary, as it will only +act when it is impossible the contract would ever be executed, but can be triggered to provide some better UI. + +Attributes emitted: + +| Key | Value | +| ------------- | ---------------------- | +| "action" | "close" | +| "sender" | msg sender | +| "proposal_id" | a UID for the proposal | ### Queries -`Threshold{}` - This returns information on the rules needed -to declare a contract a success. What percentage of the votes -and how they are tallied. +`Threshold{}` - This returns information on the rules needed to declare a contract a success. What percentage of the +votes and how they are tallied. -`Proposal{proposal_id}` - Returns the information set when -creating the proposal, along with the current status. +`Proposal{proposal_id}` - Returns the information set when creating the proposal, along with the current status. -`ListProposals{start_after, limit}` - Returns the same info -as `Proposal`, but for all proposals along with pagination. -Starts at proposal_id 1 and accending. +`ListProposals{start_after, limit}` - Returns the same info as `Proposal`, but for all proposals along with pagination. +Starts at proposal_id 1 and accending. -`ReverseProposals{start_before, limit}` - Returns the same info -as `Proposal`, but for all proposals along with pagination. -Starts at latest proposal_id and descending. (Often this -is what you will want for a UI) +`ReverseProposals{start_before, limit}` - Returns the same info as `Proposal`, but for all proposals along with +pagination. Starts at latest proposal_id and descending. (Often this is what you will want for a UI) -`Vote{proposal_id, voter}` - Returns how the given -voter (HumanAddr) voted on the proposal. (May be null) +`Vote{proposal_id, voter}` - Returns how the given voter (HumanAddr) voted on the proposal. (May be null) -`ListVotes{proposal_id, start_after, limit}` - Returns the same info -as `Vote`, but for all votes along with pagination. -Returns the voters sorted by the voters' address in -lexographically ascending order. +`ListVotes{proposal_id, start_after, limit}` - Returns the same info as `Vote`, but for all votes along with pagination. +Returns the voters sorted by the voters' address in lexographically ascending order. ## Voter Info -Information on who can vote is contract dependent. But -we will work on a common API to display some of this. +Information on who can vote is contract dependent. But we will work on a common API to display some of this. `Voter { address }` - returns voting power (weight) of this address, if any diff --git a/packages/cw4/README.md b/packages/cw4/README.md index d2203088d..7494d7fc1 100644 --- a/packages/cw4/README.md +++ b/packages/cw4/README.md @@ -1,91 +1,98 @@ # CW4 Spec: Group Members -CW4 is a spec for storing group membership, which can be combined -with CW3 multisigs. The purpose is to store a set of members/voters -that can be accessed to determine permissions in another section. - -Since this is often deployed as a contract pair, we expect this -contract to often be queried with `QueryRaw` and the internal -layout of some of the data structures becomes part of the public API. -Implementations may add more data structures, but at least -the ones laid out here should be under the specified keys and in the -same format. - -In this case, a cw3 contract could *read* an external group contract with -no significant cost besides reading local storage. However, updating -that group contract (if allowed), would be an external message and -will be charged as part of the overhead for each contract. +CW4 is a spec for storing group membership, which can be combined with CW3 multisigs. The purpose is to store a set of +members/voters that can be accessed to determine permissions in another section. + +Since this is often deployed as a contract pair, we expect this contract to often be queried with `QueryRaw` and the +internal layout of some of the data structures becomes part of the public API. Implementations may add more data +structures, but at least the ones laid out here should be under the specified keys and in the same format. + +In this case, a cw3 contract could _read_ an external group contract with no significant cost besides reading local +storage. However, updating that group contract (if allowed), would be an external message and will be charged as part of +the overhead for each contract. ## Messages -We define an `InstantiateMsg{admin, members}` to make it easy to set up a group -as part of another flow. Implementations should work with this setup, -but may add extra `Option` fields for non-essential extensions to -configure in the `instantiate` phase. +We define an `InstantiateMsg{admin, members}` to make it easy to set up a group as part of another flow. Implementations +should work with this setup, but may add extra `Option` fields for non-essential extensions to configure in the +`instantiate` phase. There are three messages supported by a group contract: `UpdateAdmin{admin}` - changes (or clears) the admin for the contract -`AddHook{addr}` - adds a contract address to be called upon every - `UpdateMembers` call. This can only be called by the admin, and care must - be taken. A contract returning an error or running out of gas will - revert the membership change (see more in Hooks section below). +Attributes emitted: + +| Key | Value | +| --------- | ------------------------ | +| "action" | "update_members" | +| "sender" | msg sender | +| "added" | count of added members | +| "removed" | count of removed members | + +`AddHook{addr}` - adds a contract address to be called upon every `UpdateMembers` call. This can only be called by the +admin, and care must be taken. A contract returning an error or running out of gas will revert the membership change +(see more in Hooks section below). + +Attributes emitted: + +| Key | Value | +| -------- | ------------ | +| "action" | "add_hook" | +| "sender" | msg sender | +| "hook" | hook address | + +`RemoveHook{addr}` - unregister a contract address that was previously set by `AddHook`. -`RemoveHook{addr}` - unregister a contract address that was previously set - by `AddHook`. +Attributes emitted: -Only the `admin` may execute any of these function. Thus, by omitting an -`admin`, we end up with a similar functionality ad `cw3-fixed-multisig`. -If we include one, it may often be desired to be a `cw3` contract that -uses this group contract as a group. This leads to a bit of chicken-and-egg -problem, but we cover how to instantiate that in +| Key | Value | +| -------- | ------------- | +| "action" | "remove_hook" | +| "sender" | msg sender | +| "hook" | hook address | + +Only the `admin` may execute any of these function. Thus, by omitting an `admin`, we end up with a similar functionality +ad `cw3-fixed-multisig`. If we include one, it may often be desired to be a `cw3` contract that uses this group contract +as a group. This leads to a bit of chicken-and-egg problem, but we cover how to instantiate that in [`cw3-flex-multisig`](../../contracts/cw3-flex-multisig/README.md#instantiation). ## Queries ### Smart -`TotalWeight{}` - Returns the total weight of all current members, - this is very useful if some conditions are defined on a "percentage of members". - -`Member{addr, height}` - Returns the weight of this voter if they are a member of the - group (may be 0), or `None` if they are not a member of the group. - If height is set and the cw4 implementation supports snapshots, - this will return the weight of that member at - the beginning of the block with the given height. - -`MemberList{start_after, limit}` - Allows us to paginate over the list - of all members. 0-weight members will be included. Removed members will not. +`TotalWeight{}` - Returns the total weight of all current members, this is very useful if some conditions are defined on +a "percentage of members". + +`Member{addr, height}` - Returns the weight of this voter if they are a member of the group (may be 0), or `None` if +they are not a member of the group. If height is set and the cw4 implementation supports snapshots, this will return the +weight of that member at the beginning of the block with the given height. + +`MemberList{start_after, limit}` - Allows us to paginate over the list of all members. 0-weight members will be +included. Removed members will not. `Admin{}` - Returns the `admin` address, or `None` if unset. ### Raw -In addition to the above "SmartQueries", which make up the public API, -we define two raw queries that are designed for more efficiency -in contract-contract calls. These use keys exported by `cw4` - -`TOTAL_KEY` - making a raw query with this key (`b"total"`) will return a - JSON-encoded `u64` - -`members_key()` - takes a `CanonicalAddr` and returns a key that can be - used for raw query (`"\x00\x07members" || addr`). This will return - empty bytes if the member is not inside the group, otherwise a - JSON-encoded `u64` - +In addition to the above "SmartQueries", which make up the public API, we define two raw queries that are designed for +more efficiency in contract-contract calls. These use keys exported by `cw4` + +`TOTAL_KEY` - making a raw query with this key (`b"total"`) will return a JSON-encoded `u64` + +`members_key()` - takes a `CanonicalAddr` and returns a key that can be used for raw query +(`"\x00\x07members" || addr`). This will return empty bytes if the member is not inside the group, otherwise a +JSON-encoded `u64` + ## Hooks -One special feature of the `cw4` contracts is they allow the admin to -register multiple hooks. These are special contracts that need to react -to changes in the group membership, and this allows them stay in sync. -Again, note this is a powerful ability and you should only set hooks -to contracts you fully trust, generally some contracts you deployed +One special feature of the `cw4` contracts is they allow the admin to register multiple hooks. These are special +contracts that need to react to changes in the group membership, and this allows them stay in sync. Again, note this is +a powerful ability and you should only set hooks to contracts you fully trust, generally some contracts you deployed alongside the group. -If a contract is registered as a hook on a cw4 contract, then anytime -`UpdateMembers` is successfully executed, the hook will receive a `handle` -call with the following format: +If a contract is registered as a hook on a cw4 contract, then anytime `UpdateMembers` is successfully executed, the hook +will receive a `handle` call with the following format: ```json { @@ -101,17 +108,13 @@ call with the following format: } ``` -See [hook.rs](./src/hook.rs) for full details. Note that this example -shows an update or an existing member. `old_weight` will -be missing if the address was added for the first time. And -`new_weight` will be missing if the address was removed. +See [hook.rs](./src/hook.rs) for full details. Note that this example shows an update or an existing member. +`old_weight` will be missing if the address was added for the first time. And `new_weight` will be missing if the +address was removed. -The receiving contract must be able to handle the `MemberChangedHookMsg` -and should only return an error if it wants to change the functionality -of the group contract (eg. a multisig that wants to prevent membership -changes while there is an open proposal). However, such cases are quite -rare and often point to fragile code. +The receiving contract must be able to handle the `MemberChangedHookMsg` and should only return an error if it wants to +change the functionality of the group contract (eg. a multisig that wants to prevent membership changes while there is +an open proposal). However, such cases are quite rare and often point to fragile code. -Note that the message sender will be the group contract that was updated. -Make sure you check this when handling, so external actors cannot -call this hook, only the trusted group. +Note that the message sender will be the group contract that was updated. Make sure you check this when handling, so +external actors cannot call this hook, only the trusted group. From 6440af28513ff76d5756e70e8afad75b7dca60db Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 29 Nov 2022 14:48:59 +0100 Subject: [PATCH 557/631] Set version: 1.0.0 --- Cargo.lock | 50 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 10 ++--- contracts/cw1-whitelist/Cargo.toml | 6 +-- contracts/cw20-base/Cargo.toml | 6 +-- contracts/cw20-ics20/Cargo.toml | 8 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 10 ++--- contracts/cw3-flex-multisig/Cargo.toml | 16 ++++---- contracts/cw4-group/Cargo.toml | 8 ++-- contracts/cw4-stake/Cargo.toml | 10 ++--- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 2 +- 15 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6eb64e5d..25548d531 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,7 +190,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -238,7 +238,7 @@ checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 0.16.0", "schemars", "semver", "serde", @@ -247,7 +247,7 @@ dependencies = [ [[package]] name = "cw1" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -257,7 +257,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -265,7 +265,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 0.16.0", + "cw2 1.0.0", "schemars", "semver", "serde", @@ -274,7 +274,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "0.16.0" +version = "1.0.0" dependencies = [ "anyhow", "assert_matches", @@ -284,7 +284,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2 0.16.0", + "cw2 1.0.0", "derivative", "schemars", "serde", @@ -294,6 +294,8 @@ dependencies = [ [[package]] name = "cw2" version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -304,9 +306,7 @@ dependencies = [ [[package]] name = "cw2" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -317,7 +317,7 @@ dependencies = [ [[package]] name = "cw20" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -328,14 +328,14 @@ dependencies = [ [[package]] name = "cw20-base" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw20", "schemars", "semver", @@ -345,14 +345,14 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw20", "schemars", "semver", @@ -362,7 +362,7 @@ dependencies = [ [[package]] name = "cw3" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -375,14 +375,14 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw20", "cw20-base", "cw3", @@ -393,14 +393,14 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw20", "cw20-base", "cw3", @@ -414,7 +414,7 @@ dependencies = [ [[package]] name = "cw4" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -425,14 +425,14 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw4", "schemars", "serde", @@ -441,14 +441,14 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "0.16.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 0.16.0", + "cw2 1.0.0", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 658eeb57d..4de952ee7 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -21,9 +21,9 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw1 = { path = "../../packages/cw1", version = "0.16.0" } -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "0.16.0", features = ["library"] } +cw1 = { path = "../../packages/cw1", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "0.16.0" schemars = "0.8.1" @@ -32,4 +32,4 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "0.16.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 47fb37e6f..24afe8967 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" @@ -21,8 +21,8 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw1 = { path = "../../packages/cw1", version = "0.16.0" } -cw2 = { path = "../../packages/cw2", version = "0.16.0" } +cw1 = { path = "../../packages/cw1", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "0.16.0" schemars = "0.8.1" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 10235b426..3f1956444 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index b74d4fd34..0e87a7b4a 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } cw-storage-plus = "0.16.0" -cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 2e9208861..8c8ca07e6 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw3 = { path = "../../packages/cw3", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw3 = { path = "../../packages/cw3", version = "1.0.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -29,6 +29,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "0.16.0" } -cw20-base = { path = "../cw20-base", version = "0.16.0", features = ["library"] } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw20-base = { path = "../cw20-base", version = "1.0.0", features = ["library"] } cw-multi-test = "0.16.0" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 46d8411ca..378884055 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw3 = { path = "../../packages/cw3", version = "0.16.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "0.16.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "0.16.0" } -cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw3 = { path = "../../packages/cw3", version = "1.0.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "1.0.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -32,6 +32,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "0.16.0" } +cw4-group = { path = "../cw4-group", version = "1.0.0" } cw-multi-test = "0.16.0" -cw20-base = { path = "../cw20-base", version = "0.16.0" } +cw20-base = { path = "../cw20-base", version = "1.0.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 3f431f4b1..526cd8e2d 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw4 = { path = "../../packages/cw4", version = "0.16.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw4 = { path = "../../packages/cw4", version = "1.0.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 0bcdc0c72..c21733189 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "0.16.0" -cw2 = { path = "../../packages/cw2", version = "0.16.0" } -cw4 = { path = "../../packages/cw4", version = "0.16.0" } -cw20 = { path = "../../packages/cw20", version = "0.16.0" } -cw-controllers = { path = "../../packages/controllers", version = "0.16.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw4 = { path = "../../packages/cw4", version = "1.0.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } cw-storage-plus = "0.16.0" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 340a9ac4a..ae90f766f 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Common controllers we can reuse in many contracts" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 8ea1f149a..7142618f9 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index e7f02ed12..efeb952a5 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-2 interface" diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index fb9534e18..6df033d96 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 61c1a8ad4..71ab870a3 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "0.16.0" -cw20 = { path = "../../packages/cw20", version = "0.16.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index ac01aea3a..057483947 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "0.16.0" +version = "1.0.0" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" From 160f311c56e97ecf1a268c957b3ea8e518a1310a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 29 Nov 2022 14:50:48 +0100 Subject: [PATCH 558/631] CHANGELOG update 1.0 --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 090cdcad1..1741cb561 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,43 @@ # Changelog +## [v1.0.0](https://github.com/CosmWasm/cw-plus/tree/v1.0.0) (2022-11-29) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.16.0...v1.0.0) + +**Implemented enhancements:** + +- Proposal for improving contract interfaces [\#391](https://github.com/CosmWasm/cw-plus/issues/391) + +**Closed issues:** + +- u [\#840](https://github.com/CosmWasm/cw-plus/issues/840) +- Workspace optimizer build failed [\#838](https://github.com/CosmWasm/cw-plus/issues/838) +- Simplify licenses [\#833](https://github.com/CosmWasm/cw-plus/issues/833) +- Update README [\#832](https://github.com/CosmWasm/cw-plus/issues/832) +- Remove `cw1155` and `cw1155-base` [\#830](https://github.com/CosmWasm/cw-plus/issues/830) +- Standardize protocol events [\#823](https://github.com/CosmWasm/cw-plus/issues/823) +- Pull out `storage-plus`, `multitest` and `utils` into a separate repo [\#816](https://github.com/CosmWasm/cw-plus/issues/816) +- Backport from DAO DAO: optionally charge to make proposal [\#742](https://github.com/CosmWasm/cw-plus/issues/742) +- Cannot find Contract address and interface verification [\#679](https://github.com/CosmWasm/cw-plus/issues/679) +- Investigate JSON Schema -\> html/md generator [\#573](https://github.com/CosmWasm/cw-plus/issues/573) +- Simple framework for gas benchmarking [\#507](https://github.com/CosmWasm/cw-plus/issues/507) +- Benchmark "ng" vs. "classic" frameworks [\#505](https://github.com/CosmWasm/cw-plus/issues/505) +- Update reimplemented cw1-whitelist contract, so it uses the custom attribute [\#496](https://github.com/CosmWasm/cw-plus/issues/496) +- Implement attribute macro for trait interface generating boilerplate specific for cw1-whitelist [\#495](https://github.com/CosmWasm/cw-plus/issues/495) +- Deriving structural interfaces for contracts [\#493](https://github.com/CosmWasm/cw-plus/issues/493) +- Accept &QuerierWrapper not &Querier in helpers [\#390](https://github.com/CosmWasm/cw-plus/issues/390) + +**Merged pull requests:** + +- Standardize spec events [\#845](https://github.com/CosmWasm/cw-plus/pull/845) ([uint](https://github.com/uint)) +- Add contributing guidelines [\#841](https://github.com/CosmWasm/cw-plus/pull/841) ([uint](https://github.com/uint)) +- Use QuerierWrapper not Querier in cw20 helpers [\#839](https://github.com/CosmWasm/cw-plus/pull/839) ([uint](https://github.com/uint)) +- Update CI to Rust 1.64 [\#837](https://github.com/CosmWasm/cw-plus/pull/837) ([uint](https://github.com/uint)) +- `README.md` update [\#836](https://github.com/CosmWasm/cw-plus/pull/836) ([uint](https://github.com/uint)) +- Remove the AGPL license [\#835](https://github.com/CosmWasm/cw-plus/pull/835) ([uint](https://github.com/uint)) +- Move `utils`, `storage-plus`, `multitest`; remove `cw1155` stuff [\#834](https://github.com/CosmWasm/cw-plus/pull/834) ([uint](https://github.com/uint)) +- Add an optional proposal deposit to cw3-flex-multisig [\#751](https://github.com/CosmWasm/cw-plus/pull/751) ([0xekez](https://github.com/0xekez)) + ## [v0.16.0](https://github.com/CosmWasm/cw-plus/tree/v0.16.0) (2022-10-14) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.15.1...v0.16.0) From 32907e8c57c7ce422e7b1938921691b687676c8b Mon Sep 17 00:00:00 2001 From: Sturdy Date: Fri, 16 Dec 2022 13:41:18 +0100 Subject: [PATCH 559/631] chore: update deps --- Cargo.lock | 295 +++++++++++++----------- contracts/cw1-subkeys/Cargo.toml | 4 +- contracts/cw1-whitelist/Cargo.toml | 6 +- contracts/cw20-base/Cargo.toml | 6 +- contracts/cw20-ics20/Cargo.toml | 4 +- contracts/cw3-fixed-multisig/Cargo.toml | 6 +- contracts/cw3-flex-multisig/Cargo.toml | 6 +- contracts/cw4-group/Cargo.toml | 4 +- contracts/cw4-stake/Cargo.toml | 4 +- packages/controllers/Cargo.toml | 4 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 2 +- packages/cw4/Cargo.toml | 2 +- 14 files changed, 183 insertions(+), 164 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25548d531..39271c4b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,22 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "anyhow" -version = "1.0.62" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "assert_matches" @@ -22,15 +33,15 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "block-buffer" @@ -43,9 +54,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -58,9 +69,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cfg-if" @@ -70,37 +81,37 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "cosmwasm-crypto" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c50d753d44148c7ff3279ac44b87b5b91e790f4c70db0e3900df211310a2bf" +checksum = "227315dc11f0bb22a273d0c43d3ba8ef52041c42cf959f09045388a89c57e661" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", "ed25519-zebra", "k256", - "rand_core 0.6.3", + "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9053ebe2ad85831e9f9e2124fa2b22807528a78b25cc447483ce2a4aadfba394" +checksum = "6fca30d51f7e5fbfa6440d8b10d7df0231bdf77e97fd3fe5d0cb79cc4822e50c" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c742fc698a88cf02ea304cc2b5bc18ef975c5bb9eff93c3e44d2cd565e1d458" +checksum = "04135971e2c3b867eb793ca4e832543c077dbf72edaef7672699190f8fcdb619" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -111,9 +122,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a7c4c07be11add09dd3af3064c4f4cbc2dc99c6859129bdaf820131730e996" +checksum = "a06c8f516a13ae481016aa35f0b5c4652459e8aee65b15b6fb51547a07cea5a0" dependencies = [ "proc-macro2", "quote", @@ -122,15 +133,16 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb8da0ae28693d892af2944319b48adc23c42725dc0fe7271b8baa38c10865da" +checksum = "b13d5a84d15cf7be17dc249a21588cdb0f7ef308907c50ce2723316a7d79c3dc" dependencies = [ "base64", "cosmwasm-crypto", "cosmwasm-derive", "derivative", "forward_ref", + "hex", "schemars", "serde", "serde-json-wasm", @@ -140,9 +152,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -155,12 +167,12 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -194,7 +206,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "schemars", "serde", @@ -203,16 +215,17 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.16.0" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7192aec80d0c01a0e5941392eea7e2b7e212ee74ca7f430bfdc899420c055ef6" +checksum = "c2eb84554bbfa6b66736abcd6a9bfdf237ee0ecb83910f746dff7f799093c80a" dependencies = [ "anyhow", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "derivative", "itertools", + "k256", "prost", "schemars", "serde", @@ -230,15 +243,26 @@ dependencies = [ "serde", ] +[[package]] +name = "cw-storage-plus" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + [[package]] name = "cw-utils" -version = "0.16.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 0.16.0", + "cw2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "semver", "serde", @@ -261,7 +285,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw1", "cw1-whitelist", @@ -281,7 +305,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw1", "cw2 1.0.0", @@ -293,13 +317,11 @@ dependencies = [ [[package]] name = "cw2" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "schemars", "serde", ] @@ -307,10 +329,12 @@ dependencies = [ [[package]] name = "cw2" version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03bdf3747540b47bc1bdaf50ba3aa5e4276ab0c2ce73e8b367ebe260cc37ff9c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 0.16.0", "schemars", "serde", ] @@ -333,7 +357,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw20", @@ -350,7 +374,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw20", @@ -380,7 +404,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw20", @@ -398,7 +422,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw20", @@ -418,7 +442,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "schemars", "serde", ] @@ -430,7 +454,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw4", @@ -446,7 +470,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", + "cw-storage-plus 1.0.1", "cw-utils", "cw2 1.0.0", "cw20", @@ -458,9 +482,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", "zeroize", @@ -488,11 +512,11 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -505,9 +529,9 @@ checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" [[package]] name = "ecdsa" -version = "0.14.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e852f4174d2a8646a0fa8a34b55797856c722f86267deb0aa1e93f7f247f800e" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -517,16 +541,16 @@ dependencies = [ [[package]] name = "ed25519-zebra" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ "curve25519-dalek", + "hashbrown", "hex", - "rand_core 0.6.3", + "rand_core 0.6.4", "serde", "sha2 0.9.9", - "thiserror", "zeroize", ] @@ -545,12 +569,12 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "digest 0.10.3", + "digest 0.10.6", "ff", "generic-array", "group", "pkcs8", - "rand_core 0.6.3", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -558,11 +582,11 @@ dependencies = [ [[package]] name = "ff" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -584,35 +608,33 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.16" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "wasi", ] [[package]] -name = "getrandom" -version = "0.2.7" +name = "group" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "ff", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "group" -version = "0.12.0" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", + "ahash", ] [[package]] @@ -627,41 +649,47 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", ] [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "k256" -version = "0.11.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2573d3fd3e4cc741affc9b5ce1a8ce36cf29f09f80f36da4309d0ae6d7854" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.2", + "sha2 0.10.6", ] [[package]] name = "libc" -version = "0.2.132" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "once_cell" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -681,9 +709,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -725,24 +753,21 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] name = "rfc6979" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", "hmac", @@ -757,9 +782,9 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "schemars" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" +checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" dependencies = [ "dyn-clone", "schemars_derive", @@ -769,9 +794,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" +checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" dependencies = [ "proc-macro2", "quote", @@ -795,15 +820,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "serde" -version = "1.0.144" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" dependencies = [ "serde_derive", ] @@ -819,9 +844,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", @@ -841,9 +866,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -865,23 +890,23 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.6", ] [[package]] name = "signature" -version = "1.6.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ea32af43239f0d353a7dd75a22d94c329c8cdaafdcb4c1c1335aa10c298a4a" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.3", - "rand_core 0.6.3", + "digest 0.10.6", + "rand_core 0.6.4", ] [[package]] @@ -908,9 +933,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -919,18 +944,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -939,15 +964,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "uint" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy", @@ -957,9 +982,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "version_check" @@ -967,12 +992,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 4de952ee7..8feddfdde 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -20,12 +20,12 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.0.0" } cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 24afe8967..a88674ed0 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -20,11 +20,11 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.0.0" } cw2 = { path = "../../packages/cw2", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } @@ -32,5 +32,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = "0.16.0" +cw-multi-test = "0.16.1" derivative = "2" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 3f1956444..fe9e49ac8 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" @@ -30,4 +30,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw-multi-test = "0.16.0" +cw-multi-test = "0.16.1" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 0e87a7b4a..523cb9459 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -19,11 +19,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } schemars = "0.8.1" semver = "1" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 8c8ca07e6..eba2cc454 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -19,10 +19,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw3 = { path = "../../packages/cw3", version = "1.0.0" } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -31,4 +31,4 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cw20 = { path = "../../packages/cw20", version = "1.0.0" } cw20-base = { path = "../cw20-base", version = "1.0.0", features = ["library"] } -cw-multi-test = "0.16.0" +cw-multi-test = "0.16.1" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 378884055..118897fab 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -19,13 +19,13 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw3 = { path = "../../packages/cw3", version = "1.0.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } @@ -33,5 +33,5 @@ thiserror = { version = "1.0.23" } [dev-dependencies] cw4-group = { path = "../cw4-group", version = "1.0.0" } -cw-multi-test = "0.16.0" +cw-multi-test = "0.16.1" cw20-base = { path = "../cw20-base", version = "1.0.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 526cd8e2d..98d261a5a 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -27,11 +27,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index c21733189..385192991 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -27,12 +27,12 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index ae90f766f..59d5489c8 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -13,8 +13,8 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.0.0" cosmwasm-std = "1.0.0" -cw-utils = "0.16.0" -cw-storage-plus = "0.16.0" +cw-utils = "1.0.1" +cw-storage-plus = "1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index efeb952a5..d825b596e 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.0.0" cosmwasm-std = { version = "1.0.0", default-features = false } -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" schemars = "0.8.1" serde = { version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 6df033d96..f8e23a08b 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = "0.16.0" +cw-utils = "1.0.1" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 71ab870a3..2a0f77095 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = "0.16.0" +cw-utils = "1.0.1" cw20 = { path = "../../packages/cw20", version = "1.0.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 057483947..78c681dbb 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = "0.16.0" +cw-storage-plus = "1" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" From 36c2430cb00e08cb1c5b9492bad42d7b078a8d9a Mon Sep 17 00:00:00 2001 From: Sturdy Date: Fri, 16 Dec 2022 17:50:29 +0100 Subject: [PATCH 560/631] chore: bump cw-storage-plus to 1.0.1 --- contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-ics20/Cargo.toml | 2 +- contracts/cw3-fixed-multisig/Cargo.toml | 2 +- contracts/cw3-flex-multisig/Cargo.toml | 2 +- contracts/cw4-group/Cargo.toml | 2 +- contracts/cw4-stake/Cargo.toml | 2 +- packages/controllers/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 2 +- packages/cw4/Cargo.toml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 8feddfdde..557bdb422 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -25,7 +25,7 @@ cw1 = { path = "../../packages/cw1", version = "1.0.0" } cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index a88674ed0..629906f4c 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -24,7 +24,7 @@ cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.0.0" } cw2 = { path = "../../packages/cw2", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index fe9e49ac8..585ee87b0 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -22,7 +22,7 @@ cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" semver = "1" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 523cb9459..942178fc2 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -23,7 +23,7 @@ cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } schemars = "0.8.1" semver = "1" diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index eba2cc454..5393df33b 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -22,7 +22,7 @@ cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw3 = { path = "../../packages/cw3", version = "1.0.0" } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 118897fab..0ce1278dd 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -25,7 +25,7 @@ cw3 = { path = "../../packages/cw3", version = "1.0.0" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.0", features = ["library"] } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 98d261a5a..c44c678cf 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -31,7 +31,7 @@ cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 385192991..2a4fdcb58 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -32,7 +32,7 @@ cw2 = { path = "../../packages/cw2", version = "1.0.0" } cw4 = { path = "../../packages/cw4", version = "1.0.0" } cw20 = { path = "../../packages/cw20", version = "1.0.0" } cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 59d5489c8..1e42094be 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -14,7 +14,7 @@ homepage = "https://cosmwasm.com" cosmwasm-schema = "1.0.0" cosmwasm-std = "1.0.0" cw-utils = "1.0.1" -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.21" } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index d825b596e..bcf08d4a6 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -11,6 +11,6 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.0.0" cosmwasm-std = { version = "1.0.0", default-features = false } -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 78c681dbb..eb6c25ebe 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = "1" +cw-storage-plus = "1.0.1" cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" From d28fa03967fd561a929cd26254e35ee748e1efee Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 16 Dec 2022 18:45:46 +0100 Subject: [PATCH 561/631] Update changelog --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1741cb561..d99087377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [v1.0.1](https://github.com/CosmWasm/cw-plus/tree/v1.0.1) (2022-12-16) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.0.0...v1.0.1) + +**Closed issues:** + +- Package versioning is a huge mess right now [\#851](https://github.com/CosmWasm/cw-plus/issues/851) +- MINT function is not working [\#848](https://github.com/CosmWasm/cw-plus/issues/848) +- Document the release process [\#810](https://github.com/CosmWasm/cw-plus/issues/810) + +**Merged pull requests:** + +- Update dependencies [\#853](https://github.com/CosmWasm/cw-plus/pull/853) ([apollo-sturdy](https://github.com/apollo-sturdy)) + ## [v1.0.0](https://github.com/CosmWasm/cw-plus/tree/v1.0.0) (2022-11-29) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v0.16.0...v1.0.0) From e0bc73032ea2abc114417d609ed81dbcf9adc77d Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Fri, 16 Dec 2022 18:46:34 +0100 Subject: [PATCH 562/631] Set version: 1.0.1 --- Cargo.lock | 54 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 10 ++--- contracts/cw1-whitelist/Cargo.toml | 6 +-- contracts/cw20-base/Cargo.toml | 6 +-- contracts/cw20-ics20/Cargo.toml | 8 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 10 ++--- contracts/cw3-flex-multisig/Cargo.toml | 16 ++++---- contracts/cw4-group/Cargo.toml | 8 ++-- contracts/cw4-stake/Cargo.toml | 10 ++--- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 6 +-- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 2 +- 15 files changed, 74 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39271c4b5..872724686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -262,7 +262,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 1.0.0", "schemars", "semver", "serde", @@ -271,7 +271,7 @@ dependencies = [ [[package]] name = "cw1" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -289,7 +289,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 1.0.0", + "cw2 1.0.1", "schemars", "semver", "serde", @@ -298,7 +298,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "assert_matches", @@ -308,7 +308,7 @@ dependencies = [ "cw-storage-plus 1.0.1", "cw-utils", "cw1", - "cw2 1.0.0", + "cw2 1.0.1", "derivative", "schemars", "serde", @@ -318,30 +318,30 @@ dependencies = [ [[package]] name = "cw2" version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03bdf3747540b47bc1bdaf50ba3aa5e4276ab0c2ce73e8b367ebe260cc37ff9c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus 0.16.0", "schemars", "serde", ] [[package]] name = "cw2" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03bdf3747540b47bc1bdaf50ba3aa5e4276ab0c2ce73e8b367ebe260cc37ff9c" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 0.16.0", + "cw-storage-plus 1.0.1", "schemars", "serde", ] [[package]] name = "cw20" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -352,14 +352,14 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw20", "schemars", "semver", @@ -369,14 +369,14 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw20", "schemars", "semver", @@ -386,7 +386,7 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -399,14 +399,14 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw20", "cw20-base", "cw3", @@ -417,14 +417,14 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw20", "cw20-base", "cw3", @@ -438,7 +438,7 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -449,14 +449,14 @@ dependencies = [ [[package]] name = "cw4-group" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw4", "schemars", "serde", @@ -465,14 +465,14 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "1.0.0" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus 1.0.1", "cw-utils", - "cw2 1.0.0", + "cw2 1.0.1", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 557bdb422..aba9b9683 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -21,9 +21,9 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.0.0" } -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library"] } +cw1 = { path = "../../packages/cw1", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.1", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "1.0.1" schemars = "0.8.1" @@ -32,4 +32,4 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.1", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 629906f4c..72f3ee505 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" @@ -21,8 +21,8 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.0.0" } -cw2 = { path = "../../packages/cw2", version = "1.0.0" } +cw1 = { path = "../../packages/cw1", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "1.0.1" schemars = "0.8.1" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 585ee87b0..b2c94a793 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 942178fc2..af4dddd33 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } cw-storage-plus = "1.0.1" -cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 5393df33b..1aa49e911 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw3 = { path = "../../packages/cw3", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw3 = { path = "../../packages/cw3", version = "1.0.1" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -29,6 +29,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw20-base = { path = "../cw20-base", version = "1.0.0", features = ["library"] } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw20-base = { path = "../cw20-base", version = "1.0.1", features = ["library"] } cw-multi-test = "0.16.1" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 0ce1278dd..c436e7830 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw3 = { path = "../../packages/cw3", version = "1.0.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.0", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw3 = { path = "../../packages/cw3", version = "1.0.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.1", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "1.0.1" } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -32,6 +32,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "1.0.0" } +cw4-group = { path = "../cw4-group", version = "1.0.1" } cw-multi-test = "0.16.1" -cw20-base = { path = "../cw20-base", version = "1.0.0" } +cw20-base = { path = "../cw20-base", version = "1.0.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index c44c678cf..91c541aed 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw4 = { path = "../../packages/cw4", version = "1.0.0" } -cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw4 = { path = "../../packages/cw4", version = "1.0.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 2a4fdcb58..957fcbb73 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.0" } -cw4 = { path = "../../packages/cw4", version = "1.0.0" } -cw20 = { path = "../../packages/cw20", version = "1.0.0" } -cw-controllers = { path = "../../packages/controllers", version = "1.0.0" } +cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw4 = { path = "../../packages/cw4", version = "1.0.1" } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 1e42094be..3b71dbb82 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Common controllers we can reuse in many contracts" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 7142618f9..7e71630fb 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index bcf08d4a6..4e7854d41 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-2 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.0.0" -cosmwasm-std = { version = "1.0.0", default-features = false } +cosmwasm-std = { version = "1.0.1", default-features = false } cw-storage-plus = "1.0.1" schemars = "0.8.1" -serde = { version = "1.0.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.1", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index f8e23a08b..daf4ad12d 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" @@ -16,4 +16,4 @@ schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } +cosmwasm-schema = { version = "1.0.1" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 2a0f77095..e145c5396 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" -cw20 = { path = "../../packages/cw20", version = "1.0.0" } +cw20 = { path = "../../packages/cw20", version = "1.0.1" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index eb6c25ebe..8d133d03d 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "1.0.0" +version = "1.0.1" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" From bd0a36448d8f0cc58c46bf00350b5d56f7f46058 Mon Sep 17 00:00:00 2001 From: Sebastian Mandrean Date: Sat, 7 Jan 2023 19:15:18 +0100 Subject: [PATCH 563/631] Remove non-existent profile --- Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6cd7a4468..c384f634c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,6 @@ incremental = false codegen-units = 1 incremental = false -[profile.release.package.cw1155-base] -codegen-units = 1 -incremental = false - [profile.release] rpath = false lto = true From 13a31cb9520ddd953e1cb1640f4bbca796886a91 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Mon, 6 Mar 2023 10:09:57 +0100 Subject: [PATCH 564/631] Update rustc to 1.64 on CI wasm-build --- .circleci/config.yml | 6 +- Cargo.lock | 158 ++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 87 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a0c2ec041..1e434e445 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -484,7 +484,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.59.0 + - image: rust:1.64.0 steps: - checkout: path: ~/project @@ -493,7 +493,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.59.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -513,7 +513,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.59.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm diff --git a/Cargo.lock b/Cargo.lock index 872724686..fd2e6d0d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "assert_matches" @@ -39,9 +39,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "block-buffer" @@ -69,9 +69,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cfg-if" @@ -81,15 +81,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-crypto" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227315dc11f0bb22a273d0c43d3ba8ef52041c42cf959f09045388a89c57e661" +checksum = "7fecd74d3a0041114110d1260f77fcb644c5d2403549b37096c44f0e643a5177" dependencies = [ "digest 0.10.6", "ed25519-zebra", @@ -100,18 +100,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fca30d51f7e5fbfa6440d8b10d7df0231bdf77e97fd3fe5d0cb79cc4822e50c" +checksum = "d5abeeb891e6d0098402e4d3d042f90451db52651d2fe14b170e69a1dd3e4115" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04135971e2c3b867eb793ca4e832543c077dbf72edaef7672699190f8fcdb619" +checksum = "9118e36843df6648fd0a626c46438f87038f296ec750cef3832cafc483c483f9" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06c8f516a13ae481016aa35f0b5c4652459e8aee65b15b6fb51547a07cea5a0" +checksum = "78d6fc9854ac14e46cb69b0f396547893f93d2847aef975950ebbe73342324f3" dependencies = [ "proc-macro2", "quote", @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13d5a84d15cf7be17dc249a21588cdb0f7ef308907c50ce2723316a7d79c3dc" +checksum = "5034c772c1369b160731aa00bb81f93733ab2884928edd8d588733d607ac5af4" dependencies = [ "base64", "cosmwasm-crypto", @@ -146,6 +146,7 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.6", "thiserror", "uint", ] @@ -206,7 +207,7 @@ version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "schemars", "serde", @@ -221,7 +222,7 @@ checksum = "c2eb84554bbfa6b66736abcd6a9bfdf237ee0ecb83910f746dff7f799093c80a" dependencies = [ "anyhow", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "derivative", "itertools", @@ -232,17 +233,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw-storage-plus" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - [[package]] name = "cw-storage-plus" version = "1.0.1" @@ -262,7 +252,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.0.0", + "cw2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "semver", "serde", @@ -285,7 +275,7 @@ version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw1", "cw1-whitelist", @@ -305,7 +295,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw1", "cw2 1.0.1", @@ -317,13 +307,11 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03bdf3747540b47bc1bdaf50ba3aa5e4276ab0c2ce73e8b367ebe260cc37ff9c" +version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 0.16.0", + "cw-storage-plus", "schemars", "serde", ] @@ -331,10 +319,12 @@ dependencies = [ [[package]] name = "cw2" version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "schemars", "serde", ] @@ -357,7 +347,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw20", @@ -374,7 +364,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw20", @@ -404,7 +394,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw20", @@ -422,7 +412,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw20", @@ -442,7 +432,7 @@ version = "1.0.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "schemars", "serde", ] @@ -454,7 +444,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw4", @@ -470,7 +460,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus 1.0.1", + "cw-storage-plus", "cw-utils", "cw2 1.0.1", "cw20", @@ -523,9 +513,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" @@ -556,9 +546,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -663,9 +653,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "k256" @@ -681,15 +671,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -709,9 +699,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -741,9 +731,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -776,15 +766,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" dependencies = [ "dyn-clone", "schemars_derive", @@ -794,9 +784,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" dependencies = [ "proc-macro2", "quote", @@ -820,33 +810,33 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.150" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -866,9 +856,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -933,9 +923,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -944,18 +934,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", @@ -982,9 +972,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "version_check" From 2f8ff20755f1617b626b9064132a3374c6c6d22e Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 3 Mar 2023 11:57:34 -0800 Subject: [PATCH 565/631] update workspace-optimizer version in README to 0.12.11 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae6b28e80..ac2bc433c 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.9 + cosmwasm/workspace-optimizer:0.12.11 ``` This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the From 8733e36f77dae909748b2ef0c995dcaebb7260ea Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 3 Mar 2023 16:00:06 -0800 Subject: [PATCH 566/631] address minor typos in cw1 comments and README --- contracts/cw1-whitelist/README.md | 4 ++-- contracts/cw1-whitelist/src/msg.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/cw1-whitelist/README.md b/contracts/cw1-whitelist/README.md index ca4f9597f..7a2e6d6cb 100644 --- a/contracts/cw1-whitelist/README.md +++ b/contracts/cw1-whitelist/README.md @@ -5,7 +5,7 @@ It contains a set of admins that are defined upon creation. Any of those admins may `Execute` any message via the contract, per the CW1 spec. -To make this slighly less minimalistic, you can allow the admin set +To make this slightly less minimalistic, you can allow the admin set to be mutable or immutable. If it is mutable, then any admin may (a) change the admin set and (b) freeze it (making it immutable). @@ -40,5 +40,5 @@ ls -l cw1_whitelist.wasm sha256sum cw1_whitelist.wasm ``` -Or for a production-ready (optimized) build, run a build command in the +Or for a production-ready (optimized) build, run a build command in the repository root: https://github.com/CosmWasm/cw-plus#compiling. diff --git a/contracts/cw1-whitelist/src/msg.rs b/contracts/cw1-whitelist/src/msg.rs index 16d7537b4..8adc0113a 100644 --- a/contracts/cw1-whitelist/src/msg.rs +++ b/contracts/cw1-whitelist/src/msg.rs @@ -51,8 +51,8 @@ pub struct AdminListResponse { #[cfg(any(test, feature = "test-utils"))] impl AdminListResponse { - /// Utility function forconverting message to its canonical form, so two messages with - /// different representation but same semantical meaning can be easly compared. + /// Utility function for converting message to its canonical form, so two messages with + /// different representation but same semantic meaning can be easily compared. /// /// It could be encapsulated in custom `PartialEq` implementation, but `PartialEq` is expected /// to be quickly, so it seems to be reasonable to keep it as representation-equality, and From 091daaf44a34e7bb95c981e27a5f9f1eb3af412c Mon Sep 17 00:00:00 2001 From: larry <26318510+larry0x@users.noreply.github.com> Date: Wed, 8 Feb 2023 02:55:24 +0000 Subject: [PATCH 567/631] add a method to assert contract version --- Cargo.lock | 1 + packages/cw2/Cargo.toml | 1 + packages/cw2/src/lib.rs | 89 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index fd2e6d0d7..9696f25d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,6 +327,7 @@ dependencies = [ "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 4e7854d41..e61642142 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -14,3 +14,4 @@ cosmwasm-std = { version = "1.0.1", default-features = false } cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.1", default-features = false, features = ["derive"] } +thiserror = "1.0.23" diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index aae498609..b3e152a75 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -18,8 +18,11 @@ For more information on this specification, please check out the */ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{CustomQuery, QuerierWrapper, QueryRequest, StdResult, Storage, WasmQuery}; +use cosmwasm_std::{ + CustomQuery, QuerierWrapper, QueryRequest, StdError, StdResult, Storage, WasmQuery, +}; use cw_storage_plus::Item; +use thiserror::Error; pub const CONTRACT: Item = Item::new("contract_info"); @@ -35,6 +38,50 @@ pub struct ContractVersion { pub version: String, } +#[derive(Error, Debug, PartialEq)] +pub enum VersionError { + #[error(transparent)] + Std(#[from] StdError), + + #[error("Contract version info not found")] + NotFound, + + #[error("Wrong contract: expecting `{expected}`, found `{found}`")] + WrongContract { expected: String, found: String }, + + #[error("Wrong contract version: expecting `{expected}`, found `{found}`")] + WrongVersion { expected: String, found: String }, +} + +/// Assert that the stored contract version info matches the given value. +/// This is useful during migrations, for making sure that the correct contract +/// is being migrated, and it's being migrated from the correct version. +pub fn assert_contract_version( + storage: &dyn Storage, + expected_contract: &str, + expected_version: &str, +) -> Result<(), VersionError> { + let Some(ContractVersion { contract, version }) = CONTRACT.may_load(storage)? else { + return Err(VersionError::NotFound); + }; + + if contract != expected_contract { + return Err(VersionError::WrongContract { + expected: expected_contract.into(), + found: contract, + }); + } + + if version != expected_version { + return Err(VersionError::WrongVersion { + expected: expected_version.into(), + found: version, + }); + } + + Ok(()) +} + /// get_contract_version can be use in migrate to read the previous version of this contract pub fn get_contract_version(store: &dyn Storage) -> StdResult { CONTRACT.load(store) @@ -98,4 +145,44 @@ mod tests { }; assert_eq!(expected, loaded); } + + #[test] + fn assert_work() { + let mut store = MockStorage::new(); + + const EXPECTED_CONTRACT: &str = "crate:mars-red-bank"; + const EXPECTED_VERSION: &str = "1.0.0"; + + // error if contract version is not set + let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); + assert_eq!(err, VersionError::NotFound); + + // wrong contract name + let wrong_contract = "crate:cw20-base"; + set_contract_version(&mut store, wrong_contract, EXPECTED_VERSION).unwrap(); + let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); + assert_eq!( + err, + VersionError::WrongContract { + expected: EXPECTED_CONTRACT.into(), + found: wrong_contract.into() + }, + ); + + // wrong contract version + let wrong_version = "8.8.8"; + set_contract_version(&mut store, EXPECTED_CONTRACT, wrong_version).unwrap(); + let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); + assert_eq!( + err, + VersionError::WrongVersion { + expected: EXPECTED_VERSION.into(), + found: wrong_version.into() + }, + ); + + // correct name and version + set_contract_version(&mut store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap(); + assert!(assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).is_ok()); + } } From f479316da301d4979c46e0b799209275783a504c Mon Sep 17 00:00:00 2001 From: larry <26318510+larry0x@users.noreply.github.com> Date: Wed, 8 Feb 2023 03:03:07 +0000 Subject: [PATCH 568/631] use older syntax --- packages/cw2/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index b3e152a75..201b77ae8 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -61,8 +61,9 @@ pub fn assert_contract_version( expected_contract: &str, expected_version: &str, ) -> Result<(), VersionError> { - let Some(ContractVersion { contract, version }) = CONTRACT.may_load(storage)? else { - return Err(VersionError::NotFound); + let ContractVersion { contract, version } = match CONTRACT.may_load(storage)? { + Some(contract) => contract, + None => return Err(VersionError::NotFound), }; if contract != expected_contract { From 10d7e5170dbbc813f17632ce2f97a96f03b0505b Mon Sep 17 00:00:00 2001 From: larry <26318510+larry0x@users.noreply.github.com> Date: Tue, 7 Mar 2023 12:32:48 +0000 Subject: [PATCH 569/631] update lockfile --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9696f25d6..d1cc452a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,6 +314,7 @@ dependencies = [ "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] @@ -327,7 +328,6 @@ dependencies = [ "cw-storage-plus", "schemars", "serde", - "thiserror", ] [[package]] From 8819d526fbe50d177dee954ab680c8abb660e3b7 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 15 Mar 2023 10:35:01 +0100 Subject: [PATCH 570/631] Remove unnecessary zero checks --- contracts/cw20-base/src/contract.rs | 36 +++++++---------------------- contracts/cw20-base/src/error.rs | 2 ++ 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 049dcbfaa..7e3547b25 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -243,10 +243,6 @@ pub fn execute_transfer( recipient: String, amount: Uint128, ) -> Result { - if amount == Uint128::zero() { - return Err(ContractError::InvalidZeroAmount {}); - } - let rcpt_addr = deps.api.addr_validate(&recipient)?; BALANCES.update( @@ -276,10 +272,6 @@ pub fn execute_burn( info: MessageInfo, amount: Uint128, ) -> Result { - if amount == Uint128::zero() { - return Err(ContractError::InvalidZeroAmount {}); - } - // lower balance BALANCES.update( deps.storage, @@ -308,10 +300,6 @@ pub fn execute_mint( recipient: String, amount: Uint128, ) -> Result { - if amount == Uint128::zero() { - return Err(ContractError::InvalidZeroAmount {}); - } - let mut config = TOKEN_INFO .may_load(deps.storage)? .ok_or(ContractError::Unauthorized {})?; @@ -358,10 +346,6 @@ pub fn execute_send( amount: Uint128, msg: Binary, ) -> Result { - if amount == Uint128::zero() { - return Err(ContractError::InvalidZeroAmount {}); - } - let rcpt_addr = deps.api.addr_validate(&contract)?; // move the tokens to the contract @@ -910,15 +894,14 @@ mod tests { assert_eq!(get_balance(deps.as_ref(), genesis), amount); assert_eq!(get_balance(deps.as_ref(), winner.clone()), prize); - // but cannot mint nothing + // Allows minting 0 let msg = ExecuteMsg::Mint { recipient: winner.clone(), amount: Uint128::zero(), }; let info = mock_info(minter.as_ref(), &[]); let env = mock_env(); - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(err, ContractError::InvalidZeroAmount {}); + execute(deps.as_mut(), env, info, msg).unwrap(); // but if it exceeds cap (even over multiple rounds), it fails // cap is enforced @@ -1171,15 +1154,14 @@ mod tests { do_instantiate(deps.as_mut(), &addr1, amount1); - // cannot transfer nothing + // Allows transferring 0 let info = mock_info(addr1.as_ref(), &[]); let env = mock_env(); let msg = ExecuteMsg::Transfer { recipient: addr2.clone(), amount: Uint128::zero(), }; - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(err, ContractError::InvalidZeroAmount {}); + execute(deps.as_mut(), env, info, msg).unwrap(); // cannot send more than we have let info = mock_info(addr1.as_ref(), &[]); @@ -1230,14 +1212,13 @@ mod tests { do_instantiate(deps.as_mut(), &addr1, amount1); - // cannot burn nothing + // Allows burning 0 let info = mock_info(addr1.as_ref(), &[]); let env = mock_env(); let msg = ExecuteMsg::Burn { amount: Uint128::zero(), }; - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(err, ContractError::InvalidZeroAmount {}); + execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( query_token_info(deps.as_ref()).unwrap().total_supply, amount1 @@ -1281,7 +1262,7 @@ mod tests { do_instantiate(deps.as_mut(), &addr1, amount1); - // cannot send nothing + // Allows sending 0 let info = mock_info(addr1.as_ref(), &[]); let env = mock_env(); let msg = ExecuteMsg::Send { @@ -1289,8 +1270,7 @@ mod tests { amount: Uint128::zero(), msg: send_msg.clone(), }; - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(err, ContractError::InvalidZeroAmount {}); + execute(deps.as_mut(), env, info, msg).unwrap(); // cannot send more than we have let info = mock_info(addr1.as_ref(), &[]); diff --git a/contracts/cw20-base/src/error.rs b/contracts/cw20-base/src/error.rs index 7cc2af491..a0b880c97 100644 --- a/contracts/cw20-base/src/error.rs +++ b/contracts/cw20-base/src/error.rs @@ -12,6 +12,8 @@ pub enum ContractError { #[error("Cannot set to own account")] CannotSetOwnAccount {}, + // Unused error case. Zero is now treated like every other value. + #[deprecated(note = "Unused. All zero amount checks have been removed")] #[error("Invalid zero amount")] InvalidZeroAmount {}, From 92c19b7d69f361bb4715452169179f265075cc7a Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:12:17 +0200 Subject: [PATCH 571/631] added optional memo --- contracts/cw20-ics20/src/contract.rs | 2 +- contracts/cw20-ics20/src/ibc.rs | 8 ++++++++ contracts/cw20-ics20/src/msg.rs | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 8d001b5ee..a55bd7845 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -135,7 +135,7 @@ pub fn execute_transfer( amount.denom(), sender.as_ref(), &msg.remote_address, - ); + ).with_memo(msg.memo); packet.validate()?; // Update the balance now (optimistically) like ibctransfer modules. diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 74f77581c..612e6b4d4 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -33,6 +33,9 @@ pub struct Ics20Packet { pub receiver: String, /// the sender address pub sender: String, + /// optional memo for the IBC transfer + #[serde(skip_serializing_if = "Option::is_none")] + pub memo: Option, } impl Ics20Packet { @@ -42,9 +45,14 @@ impl Ics20Packet { amount, sender: sender.to_string(), receiver: receiver.to_string(), + memo: None } } + pub fn with_memo(self, memo: Option) -> Self { + Ics20Packet { memo, ..self } + } + pub fn validate(&self) -> Result<(), ContractError> { if self.amount.u128() > (u64::MAX as u128) { Err(ContractError::AmountOverflow {}) diff --git a/contracts/cw20-ics20/src/msg.rs b/contracts/cw20-ics20/src/msg.rs index c137a8149..ea4290ddb 100644 --- a/contracts/cw20-ics20/src/msg.rs +++ b/contracts/cw20-ics20/src/msg.rs @@ -51,6 +51,8 @@ pub struct TransferMsg { pub remote_address: String, /// How long the packet lives in seconds. If not specified, use default_timeout pub timeout: Option, + /// An optional memo to add to the IBC transfer + pub memo: Option, } #[cw_serde] From b9bf54e39e366d14f5aa52a01bd4cd5917bec33c Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:26:20 +0200 Subject: [PATCH 572/631] cargo fmt --- contracts/cw20-ics20/src/contract.rs | 3 ++- contracts/cw20-ics20/src/ibc.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index a55bd7845..b2201b11d 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -135,7 +135,8 @@ pub fn execute_transfer( amount.denom(), sender.as_ref(), &msg.remote_address, - ).with_memo(msg.memo); + ) + .with_memo(msg.memo); packet.validate()?; // Update the balance now (optimistically) like ibctransfer modules. diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 612e6b4d4..890343901 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -45,7 +45,7 @@ impl Ics20Packet { amount, sender: sender.to_string(), receiver: receiver.to_string(), - memo: None + memo: None, } } From c41ba0a534ed947ed0f7e3fc71dda93f7deb926a Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:29:44 +0200 Subject: [PATCH 573/631] added memo to tests --- contracts/cw20-ics20/src/contract.rs | 3 +++ contracts/cw20-ics20/src/ibc.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index b2201b11d..aa94b9b86 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -432,6 +432,7 @@ mod test { channel: send_channel.to_string(), remote_address: "foreign-address".to_string(), timeout: None, + memo: None, }; // works with proper funds @@ -493,6 +494,7 @@ mod test { channel: send_channel.to_string(), remote_address: "foreign-address".to_string(), timeout: Some(7777), + memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "my-account".into(), @@ -539,6 +541,7 @@ mod test { channel: send_channel.to_string(), remote_address: "foreign-address".to_string(), timeout: Some(7777), + memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "my-account".into(), diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 890343901..ff62c90ce 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -473,6 +473,7 @@ mod test { amount: amount.into(), sender: "remote-sender".to_string(), receiver: receiver.to_string(), + memo: None, }; print!("Packet denom: {}", &data.denom); IbcPacket::new( @@ -519,6 +520,7 @@ mod test { channel: send_channel.to_string(), remote_address: "remote-rcpt".to_string(), timeout: None, + memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "local-sender".to_string(), @@ -533,6 +535,7 @@ mod test { amount: Uint128::new(987654321), sender: "local-sender".to_string(), receiver: "remote-rcpt".to_string(), + memo: None, }; let timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); assert_eq!( @@ -599,6 +602,7 @@ mod test { channel: send_channel.to_string(), remote_address: "my-remote-address".to_string(), timeout: None, + memo: None, }); let info = mock_info("local-sender", &coins(987654321, denom)); execute(deps.as_mut(), mock_env(), info, msg).unwrap(); From 7ff330c5d99cbf4d7388ceca34a592237a4b4a7b Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:34:41 +0200 Subject: [PATCH 574/631] added simple memo tests --- contracts/cw20-ics20/src/contract.rs | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index aa94b9b86..2c4ebb6bc 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -612,4 +612,50 @@ mod test { let config = query_config(deps.as_ref()).unwrap(); assert_eq!(config.default_gas_limit, Some(123456)); } + + fn test_with_memo(memo: &str) { + let send_channel = "channel-5"; + let mut deps = setup(&[send_channel, "channel-10"], &[]); + + let transfer = TransferMsg { + channel: send_channel.to_string(), + remote_address: "foreign-address".to_string(), + timeout: None, + memo: Some(memo.to_string()), + }; + + // works with proper funds + let msg = ExecuteMsg::Transfer(transfer.clone()); + let info = mock_info("foobar", &coins(1234567, "ucosm")); + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(res.messages[0].gas_limit, None); + assert_eq!(1, res.messages.len()); + if let CosmosMsg::Ibc(IbcMsg::SendPacket { + channel_id, + data, + timeout, + }) = &res.messages[0].msg + { + let expected_timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); + assert_eq!(timeout, &expected_timeout.into()); + assert_eq!(channel_id.as_str(), send_channel); + let msg: Ics20Packet = from_binary(data).unwrap(); + assert_eq!(msg.amount, Uint128::new(1234567)); + assert_eq!(msg.denom.as_str(), "ucosm"); + assert_eq!(msg.sender.as_str(), "foobar"); + assert_eq!(msg.receiver.as_str(), "foreign-address"); + } else { + panic!("Unexpected return message: {:?}", res.messages[0]); + } + } + + #[test] + fn execute_with_memo_works() { + test_with_memo("memo"); + } + + #[test] + fn execute_with_empty_string_memo_works() { + test_with_memo(""); + } } From 550bb589640771695008d51f1d5e25bf81b0de31 Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:54:35 +0200 Subject: [PATCH 575/631] added backwards compatibility test --- contracts/cw20-ics20/src/contract.rs | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 2c4ebb6bc..4a293f0e0 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -383,6 +383,7 @@ mod test { use super::*; use crate::test_helpers::*; + use cosmwasm_schema::cw_serde; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{coin, coins, CosmosMsg, IbcMsg, StdError, Uint128}; @@ -644,6 +645,12 @@ mod test { assert_eq!(msg.denom.as_str(), "ucosm"); assert_eq!(msg.sender.as_str(), "foobar"); assert_eq!(msg.receiver.as_str(), "foreign-address"); + assert_eq!( + msg.memo + .expect("Memo was None when Some was expected") + .as_str(), + memo + ); } else { panic!("Unexpected return message: {:?}", res.messages[0]); } @@ -658,4 +665,41 @@ mod test { fn execute_with_empty_string_memo_works() { test_with_memo(""); } + + #[test] + fn memo_is_backwards_compatible() { + let mut deps = setup(&["channel-5", "channel-10"], &[]); + let transfer: TransferMsg = cosmwasm_std::from_slice( + br#"{"channel": "channel-5", "remote_address": "foreign-address"}"#, + ) + .unwrap(); + + let msg = ExecuteMsg::Transfer(transfer); + let info = mock_info("foobar", &coins(1234567, "ucosm")); + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(1, res.messages.len()); + if let CosmosMsg::Ibc(IbcMsg::SendPacket { + channel_id: _, + data, + timeout: _, + }) = &res.messages[0].msg + { + let msg: Ics20Packet = from_binary(data).unwrap(); + assert_eq!(msg.memo, None); + + // This is the old version of the Ics20Packet. Deserializing into it + // should still work as the memo isn't included + #[cw_serde] + struct Ics20PacketNoMemo { + pub amount: Uint128, + pub denom: String, + pub sender: String, + pub receiver: String, + } + + let _msg: Ics20PacketNoMemo = from_binary(data).unwrap(); + } else { + panic!("Unexpected return message: {:?}", res.messages[0]); + } + } } From 7176d26bb8800849466e20fbfdd70fd5731c3313 Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Mon, 17 Apr 2023 10:55:59 +0200 Subject: [PATCH 576/631] clippy --- contracts/cw20-ics20/src/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 4a293f0e0..7c0578cd7 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -626,7 +626,7 @@ mod test { }; // works with proper funds - let msg = ExecuteMsg::Transfer(transfer.clone()); + let msg = ExecuteMsg::Transfer(transfer); let info = mock_info("foobar", &coins(1234567, "ucosm")); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(res.messages[0].gas_limit, None); From 962cb59133a1f29d4984030e7a725ba0d9cd9e22 Mon Sep 17 00:00:00 2001 From: Trevor Clarke Date: Wed, 3 May 2023 10:37:07 -0700 Subject: [PATCH 577/631] Update optimizer to latest --- scripts/optimizer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/optimizer.sh b/scripts/optimizer.sh index 5680828bc..67533a470 100755 --- a/scripts/optimizer.sh +++ b/scripts/optimizer.sh @@ -1,7 +1,7 @@ : U="cosmwasm" -V="0.12.8" +V="0.12.13" M=$(uname -m) #M="x86_64" # Force Intel arch From b904908d4be7e355eaac9081553eece1a9648314 Mon Sep 17 00:00:00 2001 From: Trevor Clarke Date: Wed, 3 May 2023 17:39:35 +0000 Subject: [PATCH 578/631] update readme workspace-optimizer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac2bc433c..12b2d787d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.11 + cosmwasm/workspace-optimizer:0.12.13 ``` This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the From 495bd76a80644ca6a77a6b165d234e7f02bb54c3 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 19 Jun 2023 17:02:13 +0200 Subject: [PATCH 579/631] Set version: 1.1.0 --- Cargo.lock | 52 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 10 ++--- contracts/cw1-whitelist/Cargo.toml | 6 +-- contracts/cw20-base/Cargo.toml | 6 +-- contracts/cw20-ics20/Cargo.toml | 8 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 10 ++--- contracts/cw3-flex-multisig/Cargo.toml | 16 ++++---- contracts/cw4-group/Cargo.toml | 8 ++-- contracts/cw4-stake/Cargo.toml | 10 ++--- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 4 +- packages/cw20/Cargo.toml | 4 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 2 +- 15 files changed, 72 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1cc452a8..5d072d7a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,7 +203,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -252,7 +252,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 1.0.1", "schemars", "semver", "serde", @@ -261,7 +261,7 @@ dependencies = [ [[package]] name = "cw1" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -271,7 +271,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -279,7 +279,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 1.0.1", + "cw2 1.1.0", "schemars", "semver", "serde", @@ -288,7 +288,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "1.0.1" +version = "1.1.0" dependencies = [ "anyhow", "assert_matches", @@ -298,7 +298,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2 1.0.1", + "cw2 1.1.0", "derivative", "schemars", "serde", @@ -308,31 +308,31 @@ dependencies = [ [[package]] name = "cw2" version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", - "thiserror", ] [[package]] name = "cw2" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw20" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -343,14 +343,14 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw20", "schemars", "semver", @@ -360,14 +360,14 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw20", "schemars", "semver", @@ -377,7 +377,7 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -390,14 +390,14 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw20", "cw20-base", "cw3", @@ -408,14 +408,14 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw20", "cw20-base", "cw3", @@ -429,7 +429,7 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -440,14 +440,14 @@ dependencies = [ [[package]] name = "cw4-group" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw4", "schemars", "serde", @@ -456,14 +456,14 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "1.0.1" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.0.1", + "cw2 1.1.0", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index aba9b9683..27caf7a1e 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -21,9 +21,9 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.0.1" } -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.1", features = ["library"] } +cw1 = { path = "../../packages/cw1", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = ["library"] } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "1.0.1" schemars = "0.8.1" @@ -32,4 +32,4 @@ thiserror = "1.0.23" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.0.1", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = ["library", "test-utils"] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 72f3ee505..39d2e886e 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" @@ -21,8 +21,8 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.0.1" } -cw2 = { path = "../../packages/cw2", version = "1.0.1" } +cw1 = { path = "../../packages/cw1", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } cosmwasm-std = { version = "1.1.0", features = ["staking"] } cw-storage-plus = "1.0.1" schemars = "0.8.1" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index b2c94a793..0a15c6db6 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index af4dddd33..3423adfcd 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } cosmwasm-std = { version = "1.1.0", features = ["stargate"] } cw-storage-plus = "1.0.1" -cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } schemars = "0.8.1" semver = "1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 1aa49e911..934faee75 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw3 = { path = "../../packages/cw3", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw3 = { path = "../../packages/cw3", version = "1.1.0" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -29,6 +29,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "1.0.1" } -cw20-base = { path = "../cw20-base", version = "1.0.1", features = ["library"] } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw20-base = { path = "../cw20-base", version = "1.1.0", features = ["library"] } cw-multi-test = "0.16.1" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index c436e7830..5d91bdde5 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw3 = { path = "../../packages/cw3", version = "1.0.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.0.1", features = ["library"] } -cw4 = { path = "../../packages/cw4", version = "1.0.1" } -cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw3 = { path = "../../packages/cw3", version = "1.1.0" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.0", features = ["library"] } +cw4 = { path = "../../packages/cw4", version = "1.1.0" } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" @@ -32,6 +32,6 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "1.0.1" } +cw4-group = { path = "../cw4-group", version = "1.1.0" } cw-multi-test = "0.16.1" -cw20-base = { path = "../cw20-base", version = "1.0.1" } +cw20-base = { path = "../cw20-base", version = "1.1.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 91c541aed..525b6d8dc 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw4 = { path = "../../packages/cw4", version = "1.0.1" } -cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw4 = { path = "../../packages/cw4", version = "1.1.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 957fcbb73..d91fedc9a 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.1.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.0.1" } -cw4 = { path = "../../packages/cw4", version = "1.0.1" } -cw20 = { path = "../../packages/cw20", version = "1.0.1" } -cw-controllers = { path = "../../packages/controllers", version = "1.0.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw4 = { path = "../../packages/cw4", version = "1.1.0" } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } cw-storage-plus = "1.0.1" cosmwasm-std = { version = "1.1.0" } schemars = "0.8.1" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 3b71dbb82..9ce102b3e 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Common controllers we can reuse in many contracts" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 7e71630fb..012dc58cc 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index e61642142..c216e2af1 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-2 interface" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cosmwasm-schema = "1.0.0" -cosmwasm-std = { version = "1.0.1", default-features = false } +cosmwasm-std = { version = "1.1.0", default-features = false } cw-storage-plus = "1.0.1" schemars = "0.8.1" serde = { version = "1.0.1", default-features = false, features = ["derive"] } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index daf4ad12d..2115dd81c 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" @@ -16,4 +16,4 @@ schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.0.1" } +cosmwasm-schema = { version = "1.1.0" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index e145c5396..a4a994c4e 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" -cw20 = { path = "../../packages/cw20", version = "1.0.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.0" } cosmwasm-schema = "1.1.0" cosmwasm-std = "1.1.0" schemars = "0.8.1" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 8d133d03d..b512761d5 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "1.0.1" +version = "1.1.0" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" From da1795b3b1c3ff4465da08233423e7af0a6c771d Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 19 Jun 2023 17:12:01 +0200 Subject: [PATCH 580/631] Update changelog --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d99087377..7f87b7c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [v1.1.0](https://github.com/CosmWasm/cw-plus/tree/v1.1.0) (2023-06-19) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.0.1...v1.1.0) + +**Closed issues:** + +- thread 'main' panicked at 'called `Result::unwrap\(\) [\#867](https://github.com/CosmWasm/cw-plus/issues/867) +- CW20 All accounts query sorting issue [\#864](https://github.com/CosmWasm/cw-plus/issues/864) +- discussion: cw20-base methods should be nonpayable, or forward funds [\#862](https://github.com/CosmWasm/cw-plus/issues/862) +- CW2: add a `cw2::VersionError` error type [\#857](https://github.com/CosmWasm/cw-plus/issues/857) + +**Merged pull requests:** + +- Update optimizer to latest [\#870](https://github.com/CosmWasm/cw-plus/pull/870) ([TrevorJTClarke](https://github.com/TrevorJTClarke)) +- Added optional memo to ics20 packets [\#868](https://github.com/CosmWasm/cw-plus/pull/868) ([nicolaslara](https://github.com/nicolaslara)) +- Remove unnecessary zero checks [\#863](https://github.com/CosmWasm/cw-plus/pull/863) ([webmaster128](https://github.com/webmaster128)) +- Update rustc to 1.64 on CI wasm-build [\#861](https://github.com/CosmWasm/cw-plus/pull/861) ([ueco-jb](https://github.com/ueco-jb)) +- Address minor typos in cw1 comments and README [\#860](https://github.com/CosmWasm/cw-plus/pull/860) ([mikedotexe](https://github.com/mikedotexe)) +- Update workspace-optimizer version in README to 0.12.11 [\#859](https://github.com/CosmWasm/cw-plus/pull/859) ([mikedotexe](https://github.com/mikedotexe)) +- CW2: add a method to assert contract version [\#858](https://github.com/CosmWasm/cw-plus/pull/858) ([larry0x](https://github.com/larry0x)) +- Remove non-existent profile [\#856](https://github.com/CosmWasm/cw-plus/pull/856) ([mandrean](https://github.com/mandrean)) + ## [v1.0.1](https://github.com/CosmWasm/cw-plus/tree/v1.0.1) (2022-12-16) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.0.0...v1.0.1) From 731d8539126273f9302197607b01e30d22d48611 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Tue, 20 Jun 2023 10:27:03 +0200 Subject: [PATCH 581/631] Fix Cargo.lock --- Cargo.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d072d7a3..1e459d794 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,7 +252,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.0.1", + "cw2 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "semver", "serde", @@ -307,20 +307,21 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +version = "1.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw2" version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", From b442203ac455fac33d056d1e228ef124e18f46af Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 20 Jun 2023 16:46:22 +0200 Subject: [PATCH 582/631] Upgrade workspace-optimizer to 0.13.0 --- .circleci/config.yml | 2 +- README.md | 4 ++-- scripts/optimizer.sh | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e434e445..61f1f60b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -559,7 +559,7 @@ jobs: - run: name: Build development contracts command: | - docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.12.8 + docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.13.0 docker cp with_code:/code/artifacts ./artifacts - run: name: Show data diff --git a/README.md b/README.md index 12b2d787d..428c35af8 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,9 @@ To compile all the contracts, run the following in the repo root: ``` docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.12.13 + cosmwasm/workspace-optimizer:0.13.0 ``` This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the diff --git a/scripts/optimizer.sh b/scripts/optimizer.sh index 67533a470..966349ee4 100755 --- a/scripts/optimizer.sh +++ b/scripts/optimizer.sh @@ -1,7 +1,7 @@ : U="cosmwasm" -V="0.12.13" +V="0.13.0" M=$(uname -m) #M="x86_64" # Force Intel arch @@ -11,6 +11,6 @@ S=${M#x86_64} S=${S:+-$S} docker run --platform $A --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ $U/workspace-optimizer$S:$V From 2e1ba8de3766b4fab630674f8014ef5e65990bdc Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 1 Sep 2023 17:58:16 +0200 Subject: [PATCH 583/631] Set the resolver version to value 2. --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c384f634c..df1b7252f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,9 @@ [workspace] members = ["packages/*", "contracts/*"] +# Resolver has to be set explicitely in workspaces, see https://github.com/rust-lang/cargo/issues/9956 +resolver = "2" + [profile.release.package.cw1-subkeys] codegen-units = 1 incremental = false From e26f97d88ccae2fc5b9ef4c0872e3f724a084080 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 1 Sep 2023 18:12:56 +0200 Subject: [PATCH 584/631] Bumped Rust version from 1.64.0 to 1.65.0 --- .circleci/config.yml | 104 +++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 61f1f60b1..58d04827c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,7 +42,7 @@ workflows: jobs: contract_cw1_subkeys: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw1-subkeys steps: - checkout: @@ -52,7 +52,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-subkeys-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -65,11 +65,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-subkeys-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw1-whitelist steps: - checkout: @@ -79,7 +79,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -92,11 +92,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw3-fixed-multisig steps: - checkout: @@ -106,7 +106,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-fixed-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -119,11 +119,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-fixed-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw3-flex-multisig steps: - checkout: @@ -133,7 +133,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-flex-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -146,11 +146,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-flex-multisig-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw4-group steps: - checkout: @@ -160,7 +160,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-group-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -173,11 +173,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-group-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw4-stake steps: - checkout: @@ -187,7 +187,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-stake-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -200,11 +200,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-stake-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw20-base steps: - checkout: @@ -214,7 +214,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-base-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -227,11 +227,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-base-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/contracts/cw20-ics20 steps: - checkout: @@ -241,7 +241,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-ics20-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -254,11 +254,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-ics20-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_controllers: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/controllers steps: - checkout: @@ -268,7 +268,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-controllers:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-controllers:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -279,11 +279,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-controllers:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-controllers:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw1 steps: - checkout: @@ -293,7 +293,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -307,11 +307,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw2: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw2 steps: - checkout: @@ -321,7 +321,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw2:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw2:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -333,11 +333,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw2:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw2:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw3 steps: - checkout: @@ -347,7 +347,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw3:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -361,11 +361,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw3:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw4 steps: - checkout: @@ -375,7 +375,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw4:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -389,11 +389,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw4:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw20 steps: - checkout: @@ -403,7 +403,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw20:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -417,11 +417,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw20:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.65.0-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project/packages/cw1155 steps: - checkout: @@ -431,7 +431,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1155:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -445,11 +445,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1155:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.65.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 steps: - checkout - run: @@ -457,7 +457,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.64.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.65.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -476,7 +476,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.64.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.65.0-{{ 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 @@ -484,7 +484,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 steps: - checkout: path: ~/project @@ -493,7 +493,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -513,7 +513,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm @@ -581,7 +581,7 @@ jobs: build_and_upload_schemas: docker: - - image: rust:1.64.0 + - image: rust:1.65.0 working_directory: ~/project steps: - checkout: From c48580a087e147dc038b4697f5510dc254160b41 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 1 Sep 2023 18:57:42 +0200 Subject: [PATCH 585/631] Fixed clippy warnings. --- contracts/cw1-whitelist/src/contract.rs | 2 +- contracts/cw20-ics20/src/contract.rs | 2 +- contracts/cw4-group/src/tests.rs | 4 ++-- contracts/cw4-stake/src/contract.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index 77f2b7ef7..b13fea207 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -111,7 +111,7 @@ pub fn execute_update_admins( fn can_execute(deps: Deps, sender: &str) -> StdResult { let cfg = ADMIN_LIST.load(deps.storage)?; - let can = cfg.is_admin(&sender); + let can = cfg.is_admin(sender); Ok(can) } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 7c0578cd7..9586bb04a 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -158,7 +158,7 @@ pub fn execute_transfer( .add_attribute("sender", &packet.sender) .add_attribute("receiver", &packet.receiver) .add_attribute("denom", &packet.denom) - .add_attribute("amount", &packet.amount.to_string()); + .add_attribute("amount", packet.amount.to_string()); Ok(res) } diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index 9ed220523..39bd87978 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -150,7 +150,7 @@ fn assert_users( // this is only valid if we are not doing a historical query if height.is_none() { // compute expected metrics - let weights = vec![user1_weight, user2_weight, user3_weight]; + let weights = [user1_weight, user2_weight, user3_weight]; let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); let count = weights.iter().filter(|x| x.is_some()).count(); @@ -357,7 +357,7 @@ fn hooks_fire() { let add_msg2 = ExecuteMsg::AddHook { addr: contract2.clone(), }; - for msg in vec![add_msg, add_msg2] { + for msg in [add_msg, add_msg2] { let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 408f3265c..20ee9fdad 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -502,7 +502,7 @@ mod tests { // this is only valid if we are not doing a historical query if height.is_none() { // compute expected metrics - let weights = vec![user1_weight, user2_weight, user3_weight]; + let weights = [user1_weight, user2_weight, user3_weight]; let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); let count = weights.iter().filter(|x| x.is_some()).count(); @@ -931,7 +931,7 @@ mod tests { let add_msg2 = ExecuteMsg::AddHook { addr: contract2.clone(), }; - for msg in vec![add_msg, add_msg2] { + for msg in [add_msg, add_msg2] { let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); } From f3322f1a7974d5a20b71e179c2b2b9cf2c036e30 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 8 Sep 2023 14:08:53 +0200 Subject: [PATCH 586/631] Bumped Rust version and cosmwasm-check version. --- .circleci/config.yml | 106 +++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 58d04827c..da3b8321c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,7 +42,7 @@ workflows: jobs: contract_cw1_subkeys: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw1-subkeys steps: - checkout: @@ -52,7 +52,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-subkeys-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -65,11 +65,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-subkeys-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw1-whitelist steps: - checkout: @@ -79,7 +79,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -92,11 +92,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw3-fixed-multisig steps: - checkout: @@ -106,7 +106,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-fixed-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -119,11 +119,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-fixed-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw3-flex-multisig steps: - checkout: @@ -133,7 +133,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-flex-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -146,11 +146,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-flex-multisig-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw4-group steps: - checkout: @@ -160,7 +160,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-group-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -173,11 +173,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-group-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw4-stake steps: - checkout: @@ -187,7 +187,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-stake-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -200,11 +200,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-stake-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw20-base steps: - checkout: @@ -214,7 +214,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-base-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -227,11 +227,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-base-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/contracts/cw20-ics20 steps: - checkout: @@ -241,7 +241,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-ics20-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -254,11 +254,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-ics20-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_controllers: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/controllers steps: - checkout: @@ -268,7 +268,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-controllers:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-controllers:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -279,11 +279,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-controllers:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-controllers:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw1 steps: - checkout: @@ -293,7 +293,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -307,11 +307,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw2: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw2 steps: - checkout: @@ -321,7 +321,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw2:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw2:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -333,11 +333,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw2:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw2:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw3 steps: - checkout: @@ -347,7 +347,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw3:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -361,11 +361,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw3:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw4 steps: - checkout: @@ -375,7 +375,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw4:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -389,11 +389,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw4:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw20 steps: - checkout: @@ -403,7 +403,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw20:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -417,11 +417,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw20:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.67.0-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project/packages/cw1155 steps: - checkout: @@ -431,7 +431,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1155:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -445,11 +445,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1155:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.67.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 steps: - checkout - run: @@ -457,7 +457,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.65.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.67.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -476,7 +476,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.65.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.67.0-{{ 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 @@ -484,7 +484,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 steps: - checkout: path: ~/project @@ -493,7 +493,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -508,12 +508,12 @@ jobs: - run: name: Install cosmwasm-check # Uses --debug for compilation speed - command: cargo install --debug --version 1.1.0 cosmwasm-check + command: cargo install --debug --version 1.4.0 cosmwasm-check - save_cache: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.65.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm @@ -581,7 +581,7 @@ jobs: build_and_upload_schemas: docker: - - image: rust:1.65.0 + - image: rust:1.67.0 working_directory: ~/project steps: - checkout: From c0c747f365acc4af4cffe8b221f129f5dcc8f9c2 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 8 Sep 2023 15:07:59 +0200 Subject: [PATCH 587/631] Fixed clippy warnings. --- contracts/cw1-subkeys/src/contract.rs | 15 +++----- contracts/cw20-base/src/contract.rs | 48 ++++++++---------------- contracts/cw20-ics20/src/contract.rs | 4 +- contracts/cw20-ics20/src/test_helpers.rs | 4 +- contracts/cw4-stake/src/contract.rs | 2 +- packages/cw20/src/balance.rs | 4 +- 6 files changed, 28 insertions(+), 49 deletions(-) diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index 0b6fe1165..dfcf8cbf9 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -549,8 +549,7 @@ mod tests { let item = self.spenders.entry(spender).or_default(); assert!( item.allowances_expire.is_none(), - "Allowances expiration for spender {} already configured", - spender + "Allowances expiration for spender {spender} already configured", ); item.allowances_expire = Some(expires); self @@ -560,8 +559,7 @@ mod tests { let item = self.spenders.entry(spender).or_default(); assert!( item.permissions.is_none(), - "Permissions for spender {} already configured", - spender + "Permissions for spender {spender} already configured", ); item.permissions = Some(permissions); self @@ -2099,8 +2097,7 @@ mod tests { assert_eq!( resp, CanExecuteResponse { can_execute: true }, - "Original message: {:#?}", - msg + "Original message: {msg:#?}", ); } } @@ -2168,8 +2165,7 @@ mod tests { assert_eq!( resp, CanExecuteResponse { can_execute: false }, - "Original message: {:#?}", - msg + "Original message: {msg:#?}", ); } } @@ -2218,8 +2214,7 @@ mod tests { assert_eq!( resp, CanExecuteResponse { can_execute: true }, - "Original message: {:#?}", - msg + "Original message: {msg:#?}", ); } } diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 7e3547b25..02608adab 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -833,8 +833,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -862,8 +861,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } } @@ -1495,8 +1493,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1548,8 +1545,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1601,8 +1597,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1654,8 +1649,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1707,8 +1701,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1760,8 +1753,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1800,8 +1792,7 @@ mod tests { assert!( matches!(err, ContractError::Std(_)), - "Expected Std error, received: {}", - err + "Expected Std error, received: {err}", ); assert_eq!( @@ -1817,8 +1808,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1870,8 +1860,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -1919,8 +1908,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -2070,8 +2058,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -2127,8 +2114,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -2177,8 +2163,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } @@ -2228,8 +2213,7 @@ mod tests { let err = query_download_logo(deps.as_ref()).unwrap_err(); assert!( matches!(err, StdError::NotFound { .. }), - "Expected StdError::NotFound, received {}", - err + "Expected StdError::NotFound, received {err}", ); } } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 9586bb04a..208427206 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -268,7 +268,7 @@ pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result StdError { - StdError::generic_err(format!("Semver: {}", err)) + StdError::generic_err(format!("Semver: {err}")) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -519,7 +519,7 @@ mod test { assert_eq!(channel_id.as_str(), send_channel); let msg: Ics20Packet = from_binary(data).unwrap(); assert_eq!(msg.amount, Uint128::new(888777666)); - assert_eq!(msg.denom, format!("cw20:{}", cw20_addr)); + assert_eq!(msg.denom, format!("cw20:{cw20_addr}")); assert_eq!(msg.sender.as_str(), "my-account"); assert_eq!(msg.receiver.as_str(), "foreign-address"); } else { diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 6f16a7e1a..27e2b4f0b 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -26,7 +26,7 @@ pub fn mock_channel(channel_id: &str) -> IbcChannel { }, IbcEndpoint { port_id: REMOTE_PORT.into(), - channel_id: format!("{}5", channel_id), + channel_id: format!("{channel_id}5"), }, ICS20_ORDERING, ICS20_VERSION, @@ -39,7 +39,7 @@ pub fn mock_channel_info(channel_id: &str) -> ChannelInfo { id: channel_id.to_string(), counterparty_endpoint: IbcEndpoint { port_id: REMOTE_PORT.into(), - channel_id: format!("{}5", channel_id), + channel_id: format!("{channel_id}5"), }, connection_id: CONNECTION_ID.into(), } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 20ee9fdad..c1b4c9343 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -284,7 +284,7 @@ pub fn execute_claim( #[inline] fn coin_to_string(amount: Uint128, denom: &str) -> String { - format!("{} {}", amount, denom) + format!("{amount} {denom}") } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/packages/cw20/src/balance.rs b/packages/cw20/src/balance.rs index 110de1b01..4e2aec7aa 100644 --- a/packages/cw20/src/balance.rs +++ b/packages/cw20/src/balance.rs @@ -23,8 +23,8 @@ impl Default for Balance { impl fmt::Display for Balance { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Balance::Native(native) => write!(f, "{}", native), - Balance::Cw20(cw20) => write!(f, "{}", cw20), + Balance::Native(native) => write!(f, "{native}"), + Balance::Cw20(cw20) => write!(f, "{cw20}"), }?; Ok(()) } From c4e25443bfd21ff7acbf8e39e973c48ad7778416 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 8 Sep 2023 15:19:42 +0200 Subject: [PATCH 588/631] Locked dependencies while installing cosmwasm-check. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index da3b8321c..bf9e3b8e5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -508,7 +508,7 @@ jobs: - run: name: Install cosmwasm-check # Uses --debug for compilation speed - command: cargo install --debug --version 1.4.0 cosmwasm-check + command: cargo install --locked --debug --version 1.4.0 cosmwasm-check - save_cache: paths: - /usr/local/cargo/registry From 2ba0ef493b81ac03b1acb32b80a33403622e1592 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 8 Sep 2023 15:28:27 +0200 Subject: [PATCH 589/631] Added llvm engine for code coverage. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bf9e3b8e5..0c56de8cf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -529,7 +529,7 @@ jobs: command: | mkdir -p cov docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin \ - sh -c "cargo tarpaulin --skip-clean --frozen --out Xml --output-dir cov" + sh -c "cargo tarpaulin --skip-clean --frozen --engine llvm --out Xml --output-dir cov" - codecov/upload: file: cov/cobertura.xml From 9dc633c676323c582489344e6b584bab9bac520a Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 8 Sep 2023 16:13:09 +0200 Subject: [PATCH 590/631] Added tests. --- contracts/cw20-ics20/src/contract.rs | 9 ++++-- packages/cw20/src/balance.rs | 45 ++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 208427206..f33aad865 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -234,7 +234,7 @@ pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Resultv2 converstion if we are v1 style + // run the v1->v2 conversion if we are v1 style if storage_version <= MIGRATE_VERSION_2.parse().map_err(from_semver)? { let old_config = v1::CONFIG.load(deps.storage)?; ADMIN.set(deps.branch(), Some(old_config.gov_contract))?; @@ -244,7 +244,7 @@ pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Resultv3 converstion if we are v2 style + // run the v2->v3 conversion if we are v2 style if storage_version <= MIGRATE_VERSION_3.parse().map_err(from_semver)? { v2::update_balances(deps.branch(), &env)?; } @@ -702,4 +702,9 @@ mod test { panic!("Unexpected return message: {:?}", res.messages[0]); } } + + #[test] + fn invalid_contract_version_should_fail() { + assert!("A.1.0".parse::().map_err(from_semver).is_err()); + } } diff --git a/packages/cw20/src/balance.rs b/packages/cw20/src/balance.rs index 4e2aec7aa..c1cf5a8cb 100644 --- a/packages/cw20/src/balance.rs +++ b/packages/cw20/src/balance.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Coin; -use std::fmt; +use std::{fmt, fmt::Display}; use cw_utils::NativeBalance; @@ -20,7 +20,7 @@ impl Default for Balance { } } -impl fmt::Display for Balance { +impl Display for Balance { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Balance::Native(native) => write!(f, "{native}"), @@ -58,3 +58,44 @@ impl From for Balance { Balance::Cw20(cw20_coin) } } + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::{Addr, Uint128}; + + #[test] + fn default_balance_is_native() { + let balance: Balance = Default::default(); + assert!(matches!(balance, Balance::Native(_))); + } + + #[test] + fn displaying_native_balance_works() { + let balance: Balance = Default::default(); + assert_eq!("", format!("{balance}",)); + } + + #[test] + fn displaying_cw20_balance_works() { + let balance = Balance::Cw20(Cw20CoinVerified { + address: Addr::unchecked("sender"), + amount: Uint128::zero(), + }); + assert_eq!("address: sender, amount: 0", format!("{balance}",)); + } + + #[test] + fn default_native_balance_is_empty() { + assert!(Balance::default().is_empty()); + } + + #[test] + fn cw20_balance_with_zero_amount_is_empty() { + assert!(Balance::Cw20(Cw20CoinVerified { + address: Addr::unchecked("sender"), + amount: Uint128::zero(), + }) + .is_empty()); + } +} From cd1531a06a641d8ae50a0f28929ad8da622e0c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Wed, 27 Sep 2023 12:45:48 +0200 Subject: [PATCH 591/631] chore: Update deps --- .circleci/config.yml | 2 +- Cargo.lock | 313 +++++++++++++++++------- contracts/cw1-subkeys/Cargo.toml | 21 +- contracts/cw1-subkeys/src/contract.rs | 36 +-- contracts/cw1-whitelist/Cargo.toml | 14 +- contracts/cw20-base/Cargo.toml | 14 +- contracts/cw20-base/src/contract.rs | 4 +- contracts/cw20-ics20/Cargo.toml | 12 +- contracts/cw3-fixed-multisig/Cargo.toml | 12 +- contracts/cw3-flex-multisig/Cargo.toml | 18 +- contracts/cw4-group/Cargo.toml | 12 +- contracts/cw4-stake/Cargo.toml | 12 +- contracts/cw4-stake/src/contract.rs | 2 +- packages/controllers/Cargo.toml | 12 +- packages/controllers/src/admin.rs | 2 +- packages/controllers/src/hooks.rs | 4 +- packages/cw1/Cargo.toml | 8 +- packages/cw2/Cargo.toml | 12 +- packages/cw20/Cargo.toml | 10 +- packages/cw3/Cargo.toml | 10 +- packages/cw4/Cargo.toml | 10 +- 21 files changed, 346 insertions(+), 194 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0c56de8cf..430d0c838 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -529,7 +529,7 @@ jobs: command: | mkdir -p cov docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin \ - sh -c "cargo tarpaulin --skip-clean --frozen --engine llvm --out Xml --output-dir cov" + sh -c "cargo tarpaulin --skip-clean --frozen --engine llvm --out xml --output-dir cov" - codecov/upload: file: cov/cobertura.xml diff --git a/Cargo.lock b/Cargo.lock index 1e459d794..eb0a13048 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,11 +31,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" -version = "0.13.1" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -61,6 +67,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "byteorder" version = "1.4.3" @@ -87,31 +99,31 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-crypto" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecd74d3a0041114110d1260f77fcb644c5d2403549b37096c44f0e643a5177" +checksum = "1ca101fbf2f76723711a30ea3771ef312ec3ec254ad021b237871ed802f9f175" dependencies = [ "digest 0.10.6", "ed25519-zebra", - "k256", + "k256 0.13.1", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5abeeb891e6d0098402e4d3d042f90451db52651d2fe14b170e69a1dd3e4115" +checksum = "c73d2dd292f60e42849d2b07c03d809cf31e128a4299a805abd6d24553bcaaf5" dependencies = [ - "syn", + "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9118e36843df6648fd0a626c46438f87038f296ec750cef3832cafc483c483f9" +checksum = "6ce34a08020433989af5cc470104f6bd22134320fe0221bd8aeb919fd5ec92d5" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -122,22 +134,23 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d6fc9854ac14e46cb69b0f396547893f93d2847aef975950ebbe73342324f3" +checksum = "96694ec781a7dd6dea1f968a2529ade009c21ad999c88b5f53d6cc495b3b96f7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5034c772c1369b160731aa00bb81f93733ab2884928edd8d588733d607ac5af4" +checksum = "2a44d3f9c25b2f864737c6605a98f2e4675d53fd8bbc7cf4d7c02475661a793d" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -148,7 +161,6 @@ dependencies = [ "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -161,16 +173,22 @@ dependencies = [ ] [[package]] -name = "crunchy" -version = "0.2.2" +name = "crypto-bigint" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -216,9 +234,9 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.16.2" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2eb84554bbfa6b66736abcd6a9bfdf237ee0ecb83910f746dff7f799093c80a" +checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" dependencies = [ "anyhow", "cosmwasm-std", @@ -226,7 +244,7 @@ dependencies = [ "cw-utils", "derivative", "itertools", - "k256", + "k256 0.11.6", "prost", "schemars", "serde", @@ -235,9 +253,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -482,6 +500,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -490,7 +518,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -509,6 +537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -525,10 +554,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der 0.7.8", + "digest 0.10.6", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -558,16 +601,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", "digest 0.10.6", - "ff", + "ff 0.12.1", "generic-array", - "group", - "pkcs8", + "group 0.12.1", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.3", + "digest 0.10.6", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.1", "subtle", "zeroize", ] @@ -582,6 +644,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "forward_ref" version = "1.0.0" @@ -596,6 +668,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -615,7 +688,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -666,11 +750,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa 0.16.7", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", +] + [[package]] name = "libc" version = "0.2.139" @@ -695,15 +793,25 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.2", ] [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -728,14 +836,14 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -761,11 +869,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ryu" version = "1.0.13" @@ -774,9 +892,9 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -786,14 +904,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] @@ -802,10 +920,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -818,9 +950,9 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -836,13 +968,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -853,7 +985,7 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -901,6 +1033,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + [[package]] name = "spki" version = "0.6.0" @@ -908,14 +1050,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "spki" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.8", +] [[package]] name = "subtle" @@ -934,24 +1080,35 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "thiserror" -version = "1.0.39" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.39" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -960,18 +1117,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-ident" version = "1.0.8" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 27caf7a1e..5a9b7193c 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,17 +19,22 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.1.0" } cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = ["library"] } -cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "1.0.1" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = "1.0.23" +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = [ + "library", +] } +cosmwasm-std = { version = "1.4.0", features = ["staking"] } +cw-storage-plus = "1.1.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = "1.0.49" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = ["library", "test-utils"] } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = [ + "library", + "test-utils", +] } diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index dfcf8cbf9..3a88caec2 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -902,7 +902,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -931,7 +931,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1034,7 +1034,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1076,7 +1076,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1115,7 +1115,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1154,7 +1154,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1200,7 +1200,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1247,7 +1247,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1362,7 +1362,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1403,7 +1403,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1444,7 +1444,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1484,7 +1484,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1517,7 +1517,7 @@ mod tests { .unwrap(); assert_eq!(rsp.messages, vec![]); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1701,7 +1701,7 @@ mod tests { rsp.messages, msgs.into_iter().map(SubMsg::new).collect::>() ); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1868,7 +1868,7 @@ mod tests { rsp.messages, msgs.into_iter().map(SubMsg::new).collect::>() ); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); assert_eq!( @@ -1903,7 +1903,7 @@ mod tests { rsp.messages, msgs.into_iter().map(SubMsg::new).collect::>() ); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); } @@ -1971,7 +1971,7 @@ mod tests { rsp.messages, msgs.into_iter().map(SubMsg::new).collect::>() ); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); } } @@ -2017,7 +2017,7 @@ mod tests { rsp.messages, msgs.into_iter().map(SubMsg::new).collect::>() ); - assert_eq!(rsp.events, vec![]); + assert!(rsp.events.is_empty()); assert_eq!(rsp.data, None); } } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 39d2e886e..b0ac6cc3b 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,18 +19,18 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.1.0" } cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cosmwasm-std = { version = "1.1.0", features = ["staking"] } -cw-storage-plus = "1.0.1" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cosmwasm-std = { version = "1.4.0", features = ["staking"] } +cw-storage-plus = "1.1.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = "0.16.1" +cw-multi-test = "0.16.5" derivative = "2" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 0a15c6db6..a9772e10e 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -18,16 +18,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cw-storage-plus = "1.0.1" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" +cw-storage-plus = "1.1.0" +cosmwasm-std = { version = "1.4.0" } +schemars = "0.8.15" semver = "1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } [dev-dependencies] -cw-multi-test = "0.16.1" +cw-multi-test = "0.16.5" diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 02608adab..30335e4b9 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -432,7 +432,7 @@ pub fn execute_update_marketing( .marketing .as_ref() .ok_or(ContractError::Unauthorized {})? - != &info.sender + != info.sender { return Err(ContractError::Unauthorized {}); } @@ -485,7 +485,7 @@ pub fn execute_upload_logo( .marketing .as_ref() .ok_or(ContractError::Unauthorized {})? - != &info.sender + != info.sender { return Err(ContractError::Unauthorized {}); } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 3423adfcd..ec6c238dc 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -18,14 +18,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cosmwasm-std = { version = "1.1.0", features = ["stargate"] } -cw-storage-plus = "1.0.1" +cosmwasm-std = { version = "1.4.0", features = ["stargate"] } +cw-storage-plus = "1.1.0" cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } -schemars = "0.8.1" +schemars = "0.8.15" semver = "1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 934faee75..e32e945da 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -18,15 +18,15 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw3 = { path = "../../packages/cw3", version = "1.1.0" } -cw-storage-plus = "1.0.1" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cw-storage-plus = "1.1.0" +cosmwasm-std = { version = "1.4.0" } +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } [dev-dependencies] cw20 = { path = "../../packages/cw20", version = "1.1.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 5d91bdde5..f59c24588 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -18,20 +18,22 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw3 = { path = "../../packages/cw3", version = "1.1.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.0", features = ["library"] } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.0", features = [ + "library", +] } cw4 = { path = "../../packages/cw4", version = "1.1.0" } cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cw-storage-plus = "1.0.1" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cw-storage-plus = "1.1.0" +cosmwasm-std = { version = "1.4.0" } +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } [dev-dependencies] cw4-group = { path = "../cw4-group", version = "1.1.0" } -cw-multi-test = "0.16.1" +cw-multi-test = "0.16.5" cw20-base = { path = "../cw20-base", version = "1.1.0" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 525b6d8dc..7b2151f27 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -26,13 +26,13 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw4 = { path = "../../packages/cw4", version = "1.1.0" } cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } -cw-storage-plus = "1.0.1" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cw-storage-plus = "1.1.0" +cosmwasm-std = { version = "1.4.0" } +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index d91fedc9a..453e0abb1 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -26,14 +26,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.0" } cw4 = { path = "../../packages/cw4", version = "1.1.0" } cw20 = { path = "../../packages/cw20", version = "1.1.0" } cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } -cw-storage-plus = "1.0.1" -cosmwasm-std = { version = "1.1.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cw-storage-plus = "1.1.0" +cosmwasm-std = { version = "1.4.0" } +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index c1b4c9343..9aa97ea30 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -90,7 +90,7 @@ pub fn execute_bond( let amount = match (&cfg.denom, &amount) { (Denom::Native(want), Balance::Native(have)) => must_pay_funds(have, want), (Denom::Cw20(want), Balance::Cw20(have)) => { - if want == &have.address { + if want == have.address { Ok(have.amount) } else { Err(ContractError::InvalidDenom(want.into())) diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 9ce102b3e..773c939c0 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -11,10 +11,10 @@ homepage = "https://cosmwasm.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-schema = "1.0.0" -cosmwasm-std = "1.0.0" +cosmwasm-schema = "1.4.0" +cosmwasm-std = "1.4.0" cw-utils = "1.0.1" -cw-storage-plus = "1.0.1" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.21" } +cw-storage-plus = "1.1.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } diff --git a/packages/controllers/src/admin.rs b/packages/controllers/src/admin.rs index 7586e5984..aac6ec8e8 100644 --- a/packages/controllers/src/admin.rs +++ b/packages/controllers/src/admin.rs @@ -46,7 +46,7 @@ impl<'a> Admin<'a> { /// we hit an error with Api or Storage usage pub fn is_admin(&self, deps: Deps, caller: &Addr) -> StdResult { match self.0.load(deps.storage)? { - Some(owner) => Ok(caller == &owner), + Some(owner) => Ok(caller == owner), None => Ok(false), } } diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs index fa7cf964c..fca49fbb4 100644 --- a/packages/controllers/src/hooks.rs +++ b/packages/controllers/src/hooks.rs @@ -43,7 +43,7 @@ impl<'a> Hooks<'a> { pub fn add_hook(&self, storage: &mut dyn Storage, addr: Addr) -> Result<(), HookError> { let mut hooks = self.0.may_load(storage)?.unwrap_or_default(); - if !hooks.iter().any(|h| h == &addr) { + if !hooks.iter().any(|h| h == addr) { hooks.push(addr); } else { return Err(HookError::HookAlreadyRegistered {}); @@ -53,7 +53,7 @@ impl<'a> Hooks<'a> { pub fn remove_hook(&self, storage: &mut dyn Storage, addr: Addr) -> Result<(), HookError> { let mut hooks = self.0.load(storage)?; - if let Some(p) = hooks.iter().position(|x| x == &addr) { + if let Some(p) = hooks.iter().position(|x| x == addr) { hooks.remove(p); } else { return Err(HookError::HookNotRegistered {}); diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 012dc58cc..acf6f0f67 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cosmwasm-schema = "1.4.0" +cosmwasm-std = "1.4.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index c216e2af1..2e86d0e3f 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -9,9 +9,9 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.0.0" -cosmwasm-std = { version = "1.1.0", default-features = false } -cw-storage-plus = "1.0.1" -schemars = "0.8.1" -serde = { version = "1.0.1", default-features = false, features = ["derive"] } -thiserror = "1.0.23" +cosmwasm-schema = "1.4.0" +cosmwasm-std = { version = "1.4.0", default-features = false } +cw-storage-plus = "1.1.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = "1.0.49" diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index 2115dd81c..e00a9977a 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -10,10 +10,10 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cosmwasm-schema = "1.4.0" +cosmwasm-std = "1.4.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } [dev-dependencies] -cosmwasm-schema = { version = "1.1.0" } +cosmwasm-schema = { version = "1.4.0" } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index a4a994c4e..f4a124228 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -11,8 +11,8 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +cosmwasm-schema = "1.4.0" +cosmwasm-std = "1.4.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.49" } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index b512761d5..daaccb723 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -9,8 +9,8 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = "1.0.1" -cosmwasm-schema = "1.1.0" -cosmwasm-std = "1.1.0" -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cw-storage-plus = "1.1.0" +cosmwasm-schema = "1.4.0" +cosmwasm-std = "1.4.0" +schemars = "0.8.15" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } From 2cfa24bb1370aab4175f53c26d51ba540fce912b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Wed, 27 Sep 2023 16:21:16 +0200 Subject: [PATCH 592/631] chore: Release v1.1.1 --- CHANGELOG.md | 16 ++++++++ Cargo.lock | 50 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 10 ++--- contracts/cw1-whitelist/Cargo.toml | 6 +-- contracts/cw20-base/Cargo.toml | 6 +-- contracts/cw20-ics20/Cargo.toml | 8 ++-- contracts/cw3-fixed-multisig/Cargo.toml | 10 ++--- contracts/cw3-flex-multisig/Cargo.toml | 16 ++++---- contracts/cw4-group/Cargo.toml | 8 ++-- contracts/cw4-stake/Cargo.toml | 10 ++--- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 4 +- packages/cw4/Cargo.toml | 2 +- 16 files changed, 85 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f87b7c64..3bc5d86a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [v1.1.1](https://github.com/CosmWasm/cw-plus/tree/v1.1.1) (2023-09-27) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.0...v1.1.1) + +**Closed issues:** + +- Issue in providing cw4_stake.wasm contract values for initiating [\#878](https://github.com/CosmWasm/cw-plus/issues/878) +- Bump cw2 version [\#873](https://github.com/CosmWasm/cw-plus/issues/873) + +**Merged pull requests:** + +- Update deps [\#882](https://github.com/CosmWasm/cw-plus/pull/882) ([jawoznia](https://github.com/jawoznia)) +- Bumped Rust version and cosmwasm-check version [\#881](https://github.com/CosmWasm/cw-plus/pull/881) ([DariuszDepta](https://github.com/DariuszDepta)) +- Set the resolver version to value 2 [\#880](https://github.com/CosmWasm/cw-plus/pull/880) ([DariuszDepta](https://github.com/DariuszDepta)) +- Upgrade workspace-optimizer to 0.13.0 [\#876](https://github.com/CosmWasm/cw-plus/pull/876) ([webmaster128](https://github.com/webmaster128)) + ## [v1.1.0](https://github.com/CosmWasm/cw-plus/tree/v1.1.0) (2023-06-19) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.0.1...v1.1.0) diff --git a/Cargo.lock b/Cargo.lock index eb0a13048..b9f643562 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -270,7 +270,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 1.1.0", "schemars", "semver", "serde", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "cw1" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -289,7 +289,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -297,7 +297,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 1.1.0", + "cw2 1.1.1", "schemars", "semver", "serde", @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "1.1.0" +version = "1.1.1" dependencies = [ "anyhow", "assert_matches", @@ -316,7 +316,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2 1.1.0", + "cw2 1.1.1", "derivative", "schemars", "serde", @@ -326,6 +326,8 @@ dependencies = [ [[package]] name = "cw2" version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -337,9 +339,7 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -351,7 +351,7 @@ dependencies = [ [[package]] name = "cw20" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -362,14 +362,14 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw20", "schemars", "semver", @@ -379,14 +379,14 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw20", "schemars", "semver", @@ -396,7 +396,7 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -409,14 +409,14 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw20", "cw20-base", "cw3", @@ -427,14 +427,14 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw20", "cw20-base", "cw3", @@ -448,7 +448,7 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -459,14 +459,14 @@ dependencies = [ [[package]] name = "cw4-group" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw4", "schemars", "serde", @@ -475,14 +475,14 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "1.1.0" +version = "1.1.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.0", + "cw2 1.1.1", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 5a9b7193c..9981f2631 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -21,9 +21,9 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.0" } -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = [ +cw1 = { path = "../../packages/cw1", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.1", features = [ "library", ] } cosmwasm-std = { version = "1.4.0", features = ["staking"] } @@ -34,7 +34,7 @@ thiserror = "1.0.49" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.0", features = [ +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.1", features = [ "library", "test-utils", ] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index b0ac6cc3b..0ae1b75d0 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" @@ -21,8 +21,8 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.0" } -cw2 = { path = "../../packages/cw2", version = "1.1.0" } +cw1 = { path = "../../packages/cw1", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } cosmwasm-std = { version = "1.4.0", features = ["staking"] } cw-storage-plus = "1.1.0" schemars = "0.8.15" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index a9772e10e..d9b40fd3c 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index ec6c238dc..ac575063b 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } cosmwasm-std = { version = "1.4.0", features = ["stargate"] } cw-storage-plus = "1.1.0" -cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } schemars = "0.8.15" semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index e32e945da..cffa81594 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw3 = { path = "../../packages/cw3", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw3 = { path = "../../packages/cw3", version = "1.1.1" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" @@ -29,6 +29,6 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = { version = "1.0.49" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cw20-base = { path = "../cw20-base", version = "1.1.0", features = ["library"] } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw20-base = { path = "../cw20-base", version = "1.1.1", features = ["library"] } cw-multi-test = "0.16.1" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index f59c24588..33394d537 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -20,13 +20,13 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw3 = { path = "../../packages/cw3", version = "1.1.0" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.0", features = [ +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw3 = { path = "../../packages/cw3", version = "1.1.1" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.1", features = [ "library", ] } -cw4 = { path = "../../packages/cw4", version = "1.1.0" } -cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw4 = { path = "../../packages/cw4", version = "1.1.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" @@ -34,6 +34,6 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = { version = "1.0.49" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "1.1.0" } +cw4-group = { path = "../cw4-group", version = "1.1.1" } cw-multi-test = "0.16.5" -cw20-base = { path = "../cw20-base", version = "1.1.0" } +cw20-base = { path = "../cw20-base", version = "1.1.1" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 7b2151f27..336c83c5b 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw4 = { path = "../../packages/cw4", version = "1.1.0" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw4 = { path = "../../packages/cw4", version = "1.1.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 453e0abb1..0af5c2026 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.0" } -cw4 = { path = "../../packages/cw4", version = "1.1.0" } -cw20 = { path = "../../packages/cw20", version = "1.1.0" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.0" } +cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw4 = { path = "../../packages/cw4", version = "1.1.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 773c939c0..7e34bd203 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Common controllers we can reuse in many contracts" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index acf6f0f67..a8f782148 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index 2e86d0e3f..ba9f1779e 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-2 interface" diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index e00a9977a..d4f117046 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index f4a124228..4a99395a7 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" -cw20 = { path = "../../packages/cw20", version = "1.1.0" } +cw20 = { path = "../../packages/cw20", version = "1.1.1" } cosmwasm-schema = "1.4.0" cosmwasm-std = "1.4.0" schemars = "0.8.15" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index daaccb723..3ebb573d3 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "1.1.0" +version = "1.1.1" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" From 84148a020aba4df3c32173740973611080bf1403 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 13 Nov 2023 10:51:40 +0100 Subject: [PATCH 593/631] Add ensure_from_older_version --- Cargo.lock | 5 +- packages/cw2/Cargo.toml | 1 + packages/cw2/README.md | 4 +- packages/cw2/src/lib.rs | 4 ++ packages/cw2/src/migrate.rs | 100 ++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 packages/cw2/src/migrate.rs diff --git a/Cargo.lock b/Cargo.lock index b9f643562..bfb962074 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -345,6 +345,7 @@ dependencies = [ "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] @@ -944,9 +945,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index ba9f1779e..aa94c27af 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -13,5 +13,6 @@ cosmwasm-schema = "1.4.0" cosmwasm-std = { version = "1.4.0", default-features = false } cw-storage-plus = "1.1.0" schemars = "0.8.15" +semver = { version = "1.0.20", default-features = false } serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = "1.0.49" diff --git a/packages/cw2/README.md b/packages/cw2/README.md index b80c599a2..bfbb82eae 100644 --- a/packages/cw2/README.md +++ b/packages/cw2/README.md @@ -20,9 +20,11 @@ wasmd query wasm contract-state raw [contract_addr] 636F6E74726163745F696E666F - ``` When the `migrate` function is called, then the new contract -can read that data andsee if this is an expected contract we can +can read that data and see if this is an expected contract we can migrate from. And also contain extra version information if we support multiple migrate paths. +This crate provides an `ensure_from_older_version` helper that +handles this. ### Data structures diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs index 201b77ae8..808008afb 100644 --- a/packages/cw2/src/lib.rs +++ b/packages/cw2/src/lib.rs @@ -24,6 +24,10 @@ use cosmwasm_std::{ use cw_storage_plus::Item; use thiserror::Error; +mod migrate; + +pub use migrate::ensure_from_older_version; + pub const CONTRACT: Item = Item::new("contract_info"); #[cw_serde] diff --git a/packages/cw2/src/migrate.rs b/packages/cw2/src/migrate.rs new file mode 100644 index 000000000..588127617 --- /dev/null +++ b/packages/cw2/src/migrate.rs @@ -0,0 +1,100 @@ +use crate::{get_contract_version, set_contract_version}; +use cosmwasm_std::{StdError, StdResult, Storage}; +use semver::Version; + +/// This function not only validates that the right contract and version can be migrated, but also +/// updates the contract version from the original (stored) version to the new version. +/// It returns the original version for the convenience of doing external checks. +pub fn ensure_from_older_version( + storage: &mut dyn Storage, + name: &str, + new_version: &str, +) -> StdResult { + let version: Version = new_version.parse().map_err(from_semver)?; + let stored = get_contract_version(storage)?; + let storage_version: Version = stored.version.parse().map_err(from_semver)?; + + if name != stored.contract { + let msg = format!("Cannot migrate from {} to {}", stored.contract, name); + return Err(StdError::generic_err(msg)); + } + + if storage_version > version { + let msg = format!( + "Cannot migrate from newer version ({}) to older ({})", + stored.version, new_version + ); + return Err(StdError::generic_err(msg)); + } + if storage_version < version { + // we don't need to save anything if migrating from the same version + set_contract_version(storage, name, new_version)?; + } + + Ok(storage_version) +} + +fn from_semver(err: semver::Error) -> StdError { + StdError::generic_err(format!("Semver: {}", err)) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::MockStorage; + + #[test] + fn accepts_identical_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); + // ensure this matches + ensure_from_older_version(&mut storage, "demo", "0.1.2").unwrap(); + } + + #[test] + fn accepts_and_updates_on_newer_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.4.0").unwrap(); + // ensure this matches + let original_version = ensure_from_older_version(&mut storage, "demo", "0.4.2").unwrap(); + + // check the original version is returned + assert_eq!(original_version.to_string(), "0.4.0".to_string()); + + // check the version is updated + let stored = get_contract_version(&storage).unwrap(); + assert_eq!(stored.contract, "demo".to_string()); + assert_eq!(stored.version, "0.4.2".to_string()); + } + + #[test] + fn errors_on_name_mismatch() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); + // ensure this matches + let err = ensure_from_older_version(&mut storage, "cw20-base", "0.1.2").unwrap_err(); + assert!(err.to_string().contains("cw20-base"), "{}", err); + assert!(err.to_string().contains("demo"), "{}", err); + } + + #[test] + fn errors_on_older_version() { + let mut storage = MockStorage::new(); + set_contract_version(&mut storage, "demo", "0.10.2").unwrap(); + // ensure this matches + let err = ensure_from_older_version(&mut storage, "demo", "0.9.7").unwrap_err(); + assert!(err.to_string().contains("0.10.2"), "{}", err); + assert!(err.to_string().contains("0.9.7"), "{}", err); + } + + #[test] + fn errors_on_broken_version() { + let mut storage = MockStorage::new(); + let err = ensure_from_older_version(&mut storage, "demo", "0.a.7").unwrap_err(); + assert!( + err.to_string().contains("unexpected character 'a'"), + "{}", + err + ); + } +} From bf1285a659de668765cd67c96485395b32575a59 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 13 Nov 2023 11:18:45 +0100 Subject: [PATCH 594/631] Fix lint --- packages/cw2/src/migrate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cw2/src/migrate.rs b/packages/cw2/src/migrate.rs index 588127617..c92ce2152 100644 --- a/packages/cw2/src/migrate.rs +++ b/packages/cw2/src/migrate.rs @@ -35,7 +35,7 @@ pub fn ensure_from_older_version( } fn from_semver(err: semver::Error) -> StdError { - StdError::generic_err(format!("Semver: {}", err)) + StdError::generic_err(format!("Semver: {err}")) } #[cfg(test)] From 9eca047c11701ed39bf4acdfcc42f58f25d2c89d Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 13 Nov 2023 11:27:52 +0100 Subject: [PATCH 595/631] Use cw2::ensure_from_older_version --- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-base/src/contract.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index d9b40fd3c..2b35f1bbd 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -19,7 +19,6 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" cw2 = { path = "../../packages/cw2", version = "1.1.1" } cw20 = { path = "../../packages/cw20", version = "1.1.1" } cw-storage-plus = "1.1.0" @@ -31,3 +30,4 @@ thiserror = { version = "1.0.49" } [dev-dependencies] cw-multi-test = "0.16.5" +cw-utils = "1.0.1" diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 30335e4b9..6f92ac227 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -5,12 +5,11 @@ use cosmwasm_std::{ to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; -use cw2::set_contract_version; +use cw2::{ensure_from_older_version, set_contract_version}; use cw20::{ BalanceResponse, Cw20Coin, Cw20ReceiveMsg, DownloadLogoResponse, EmbeddedLogo, Logo, LogoInfo, MarketingInfoResponse, MinterResponse, TokenInfoResponse, }; -use cw_utils::ensure_from_older_version; use crate::allowances::{ execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from, From 9ce2eb86b312541868cb57f6961f44571f91b171 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 23 Nov 2023 15:01:17 +0000 Subject: [PATCH 596/631] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bc5d86a7..f2df2e2c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [1.1.2](https://github.com/CosmWasm/cw-plus/tree/1.1.2) (2023-11-23) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.1...1.1.2) + +**Merged pull requests:** + +- Add `ensure_from_older_version` [\#886](https://github.com/CosmWasm/cw-plus/pull/886) ([chipshort](https://github.com/chipshort)) + ## [v1.1.1](https://github.com/CosmWasm/cw-plus/tree/v1.1.1) (2023-09-27) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.0...v1.1.1) From bf3dd9656f2910c7ac4ff6e1dfc2d223741199a1 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 23 Nov 2023 15:01:29 +0000 Subject: [PATCH 597/631] Set version: 1.1.2 --- Cargo.lock | 44 ++++++++++++------------- contracts/cw1-subkeys/Cargo.toml | 10 +++--- contracts/cw1-whitelist/Cargo.toml | 6 ++-- contracts/cw20-base/Cargo.toml | 6 ++-- contracts/cw20-ics20/Cargo.toml | 8 ++--- contracts/cw3-fixed-multisig/Cargo.toml | 10 +++--- contracts/cw3-flex-multisig/Cargo.toml | 16 ++++----- contracts/cw4-group/Cargo.toml | 8 ++--- contracts/cw4-stake/Cargo.toml | 10 +++--- packages/controllers/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- packages/cw2/Cargo.toml | 2 +- packages/cw20/Cargo.toml | 2 +- packages/cw3/Cargo.toml | 4 +-- packages/cw4/Cargo.toml | 2 +- 15 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfb962074..0c9c4bbdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "cw1" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -289,7 +289,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -297,7 +297,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 1.1.1", + "cw2 1.1.2", "schemars", "semver", "serde", @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "1.1.1" +version = "1.1.2" dependencies = [ "anyhow", "assert_matches", @@ -316,7 +316,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2 1.1.1", + "cw2 1.1.2", "derivative", "schemars", "serde", @@ -339,7 +339,7 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -352,7 +352,7 @@ dependencies = [ [[package]] name = "cw20" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -363,14 +363,14 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw20", "schemars", "semver", @@ -380,14 +380,14 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw20", "schemars", "semver", @@ -397,7 +397,7 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -410,14 +410,14 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw20", "cw20-base", "cw3", @@ -428,14 +428,14 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw20", "cw20-base", "cw3", @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -460,14 +460,14 @@ dependencies = [ [[package]] name = "cw4-group" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw4", "schemars", "serde", @@ -476,14 +476,14 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "1.1.1" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.1", + "cw2 1.1.2", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 9981f2631..61c56dbe2 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" @@ -21,9 +21,9 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.1" } -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.1", features = [ +cw1 = { path = "../../packages/cw1", version = "1.1.2" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.2", features = [ "library", ] } cosmwasm-std = { version = "1.4.0", features = ["staking"] } @@ -34,7 +34,7 @@ thiserror = "1.0.49" semver = "1" [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.1", features = [ +cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.2", features = [ "library", "test-utils", ] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 0ae1b75d0..7f4f3cbf3 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" @@ -21,8 +21,8 @@ test-utils = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.1" } -cw2 = { path = "../../packages/cw2", version = "1.1.1" } +cw1 = { path = "../../packages/cw1", version = "1.1.2" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } cosmwasm-std = { version = "1.4.0", features = ["staking"] } cw-storage-plus = "1.1.0" schemars = "0.8.15" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 2b35f1bbd..2f49e44c4 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -19,8 +19,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index ac575063b..b4c61eca0 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } cosmwasm-std = { version = "1.4.0", features = ["stargate"] } cw-storage-plus = "1.1.0" -cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } schemars = "0.8.15" semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index cffa81594..fa0cd97f7 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -20,8 +20,8 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw3 = { path = "../../packages/cw3", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw3 = { path = "../../packages/cw3", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" @@ -29,6 +29,6 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = { version = "1.0.49" } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "1.1.1" } -cw20-base = { path = "../cw20-base", version = "1.1.1", features = ["library"] } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } +cw20-base = { path = "../cw20-base", version = "1.1.2", features = ["library"] } cw-multi-test = "0.16.1" diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 33394d537..f25a684b9 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -20,13 +20,13 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw3 = { path = "../../packages/cw3", version = "1.1.1" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.1", features = [ +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw3 = { path = "../../packages/cw3", version = "1.1.2" } +cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.2", features = [ "library", ] } -cw4 = { path = "../../packages/cw4", version = "1.1.1" } -cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw4 = { path = "../../packages/cw4", version = "1.1.2" } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" @@ -34,6 +34,6 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = { version = "1.0.49" } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "1.1.1" } +cw4-group = { path = "../cw4-group", version = "1.1.2" } cw-multi-test = "0.16.5" -cw20-base = { path = "../cw20-base", version = "1.1.1" } +cw20-base = { path = "../cw20-base", version = "1.1.2" } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 336c83c5b..f1e38cb86 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw4 = { path = "../../packages/cw4", version = "1.1.1" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw4 = { path = "../../packages/cw4", version = "1.1.2" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 0af5c2026..fd58c36eb 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.1" } -cw4 = { path = "../../packages/cw4", version = "1.1.1" } -cw20 = { path = "../../packages/cw20", version = "1.1.1" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.1" } +cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw4 = { path = "../../packages/cw4", version = "1.1.2" } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } +cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml index 7e34bd203..b2e199412 100644 --- a/packages/controllers/Cargo.toml +++ b/packages/controllers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-controllers" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Common controllers we can reuse in many contracts" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index a8f782148..3b08d1539 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml index aa94c27af..5e7804005 100644 --- a/packages/cw2/Cargo.toml +++ b/packages/cw2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw2" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-2 interface" diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index d4f117046..ad89d4009 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 4a99395a7..2ac6bc2cd 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -10,7 +10,7 @@ homepage = "https://cosmwasm.com" [dependencies] cw-utils = "1.0.1" -cw20 = { path = "../../packages/cw20", version = "1.1.1" } +cw20 = { path = "../../packages/cw20", version = "1.1.2" } cosmwasm-schema = "1.4.0" cosmwasm-std = "1.4.0" schemars = "0.8.15" diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 3ebb573d3..b3d3c26fd 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "1.1.1" +version = "1.1.2" authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" From 03a811410381b465a82c19f83e88618647b0fc16 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 23 Nov 2023 17:24:03 +0000 Subject: [PATCH 598/631] Fix Cargo.lock for publishing --- Cargo.lock | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c9c4bbdd..88d85f061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,13 +264,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.0", + "cw2 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "semver", "serde", @@ -325,14 +325,13 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] @@ -340,6 +339,8 @@ dependencies = [ [[package]] name = "cw2" version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", From 96d7a0f8dcfb7d9de10bded06d106de6bcdf7722 Mon Sep 17 00:00:00 2001 From: Chanaka Karunarathne Date: Mon, 5 Feb 2024 17:52:21 +0700 Subject: [PATCH 599/631] Update README.md --- contracts/cw3-flex-multisig/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/cw3-flex-multisig/README.md b/contracts/cw3-flex-multisig/README.md index 3225d94d1..fc30d128a 100644 --- a/contracts/cw3-flex-multisig/README.md +++ b/contracts/cw3-flex-multisig/README.md @@ -76,9 +76,9 @@ Once you are happy with the content, you can compile it to wasm via: ``` RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw3_fixed_multisig.wasm . -ls -l cw3_fixed_multisig.wasm -sha256sum cw3_fixed_multisig.wasm +cp ../../target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm . +ls -l cw3_flex_multisig.wasm +sha256sum cw3_flex_multisig.wasm ``` Or for a production-ready (optimized) build, run a build command in From 105dce5c78257a618fc382e4d490cb69886a5ee3 Mon Sep 17 00:00:00 2001 From: Etienne Napoleone Date: Mon, 5 Feb 2024 14:35:04 +0100 Subject: [PATCH 600/631] docs: update token info response --- packages/cw20/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cw20/README.md b/packages/cw20/README.md index 8eb118445..9d3e62924 100644 --- a/packages/cw20/README.md +++ b/packages/cw20/README.md @@ -56,7 +56,7 @@ Attributes emitted: Return type is `BalanceResponse{balance}`. `TokenInfo{}` - Returns the token info of the contract. Return type is -`TokenInfoResponse{name, symbol, decimal, total_supply}`. +`TokenInfoResponse{name, symbol, decimals, total_supply}`. ### Receiver From 835dc9af4bfbe52eed37bbd57242fbf17c4eeca3 Mon Sep 17 00:00:00 2001 From: Tomasz Kulik Date: Mon, 5 Feb 2024 11:06:16 +0100 Subject: [PATCH 601/631] chore: Remove 'controllers' and 'cw2' from this repo. They are recreated in cw-minus --- .circleci/config.yml | 53 --- Cargo.lock | 33 +- contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- contracts/cw20-base/Cargo.toml | 2 +- contracts/cw20-ics20/Cargo.toml | 4 +- contracts/cw3-fixed-multisig/Cargo.toml | 2 +- contracts/cw3-flex-multisig/Cargo.toml | 2 +- contracts/cw4-group/Cargo.toml | 4 +- contracts/cw4-stake/Cargo.toml | 4 +- packages/controllers/Cargo.toml | 20 - packages/controllers/README.md | 16 - packages/controllers/src/admin.rs | 184 -------- packages/controllers/src/claim.rs | 587 ------------------------ packages/controllers/src/hooks.rs | 131 ------ packages/controllers/src/lib.rs | 23 - packages/cw2/.cargo/config | 3 - packages/cw2/Cargo.toml | 18 - packages/cw2/README.md | 60 --- packages/cw2/src/lib.rs | 193 -------- packages/cw2/src/migrate.rs | 100 ---- 21 files changed, 22 insertions(+), 1421 deletions(-) delete mode 100644 packages/controllers/Cargo.toml delete mode 100644 packages/controllers/README.md delete mode 100644 packages/controllers/src/admin.rs delete mode 100644 packages/controllers/src/claim.rs delete mode 100644 packages/controllers/src/hooks.rs delete mode 100644 packages/controllers/src/lib.rs delete mode 100644 packages/cw2/.cargo/config delete mode 100644 packages/cw2/Cargo.toml delete mode 100644 packages/cw2/README.md delete mode 100644 packages/cw2/src/lib.rs delete mode 100644 packages/cw2/src/migrate.rs diff --git a/.circleci/config.yml b/.circleci/config.yml index 430d0c838..166088745 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,9 +15,7 @@ workflows: - contract_cw4_stake - contract_cw20_base - contract_cw20_ics20 - - package_controllers - package_cw1 - - package_cw2 - package_cw3 - package_cw4 - package_cw20 @@ -256,31 +254,6 @@ jobs: - target key: cargocache-cw20-ics20-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} - package_controllers: - docker: - - image: rust:1.67.0 - working_directory: ~/project/packages/controllers - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version; rustup target list --installed - - restore_cache: - keys: - - cargocache-v2-controllers:1.67.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Build library for native target - command: cargo build --locked - - run: - name: Run unit tests - command: cargo test --locked - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-controllers:1.67.0-{{ checksum "~/project/Cargo.lock" }} - package_cw1: docker: - image: rust:1.67.0 @@ -309,32 +282,6 @@ jobs: - target key: cargocache-v2-cw1:1.67.0-{{ checksum "~/project/Cargo.lock" }} - package_cw2: - docker: - - image: rust:1.67.0 - working_directory: ~/project/packages/cw2 - steps: - - checkout: - path: ~/project - - run: - name: Version information - command: rustc --version; cargo --version; rustup --version; rustup target list --installed - - restore_cache: - keys: - - cargocache-v2-cw2:1.67.0-{{ checksum "~/project/Cargo.lock" }} - - run: - name: Build library for native target - command: cargo build --locked - - run: - name: Run unit tests - command: cargo test --locked - # note: there are no schemas to generate - - save_cache: - paths: - - /usr/local/cargo/registry - - target - key: cargocache-v2-cw2:1.67.0-{{ checksum "~/project/Cargo.lock" }} - package_cw3: docker: - image: rust:1.67.0 diff --git a/Cargo.lock b/Cargo.lock index 88d85f061..4394950e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,6 +222,8 @@ dependencies = [ [[package]] name = "cw-controllers" version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -270,7 +272,7 @@ checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2", "schemars", "semver", "serde", @@ -297,7 +299,7 @@ dependencies = [ "cw-utils", "cw1", "cw1-whitelist", - "cw2 1.1.2", + "cw2", "schemars", "semver", "serde", @@ -316,26 +318,13 @@ dependencies = [ "cw-storage-plus", "cw-utils", "cw1", - "cw2 1.1.2", + "cw2", "derivative", "schemars", "serde", "thiserror", ] -[[package]] -name = "cw2" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "semver", - "serde", - "thiserror", -] - [[package]] name = "cw2" version = "1.1.2" @@ -371,7 +360,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw20", "schemars", "semver", @@ -388,7 +377,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw20", "schemars", "semver", @@ -418,7 +407,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw20", "cw20-base", "cw3", @@ -436,7 +425,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw20", "cw20-base", "cw3", @@ -468,7 +457,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw4", "schemars", "serde", @@ -484,7 +473,7 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw-utils", - "cw2 1.1.2", + "cw2", "cw20", "cw4", "schemars", diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 61c56dbe2..76c335697 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.1.2" } -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.2", features = [ "library", ] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 7f4f3cbf3..9089808d3 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -22,7 +22,7 @@ test-utils = [] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" cw1 = { path = "../../packages/cw1", version = "1.1.2" } -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cosmwasm-std = { version = "1.4.0", features = ["staking"] } cw-storage-plus = "1.1.0" schemars = "0.8.15" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index 2f49e44c4..e35a05d56 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -19,7 +19,7 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw20 = { path = "../../packages/cw20", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index b4c61eca0..a73654450 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -20,11 +20,11 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw20 = { path = "../../packages/cw20", version = "1.1.2" } cosmwasm-std = { version = "1.4.0", features = ["stargate"] } cw-storage-plus = "1.1.0" -cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } +cw-controllers = "1.1.2" schemars = "0.8.15" semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index fa0cd97f7..430e65f93 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -20,7 +20,7 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw3 = { path = "../../packages/cw3", version = "1.1.2" } cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index f25a684b9..76d334397 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -20,7 +20,7 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw3 = { path = "../../packages/cw3", version = "1.1.2" } cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.2", features = [ "library", diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index f1e38cb86..bdfecff9b 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -28,9 +28,9 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw4 = { path = "../../packages/cw4", version = "1.1.2" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } +cw-controllers = "1.1.2" cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index fd58c36eb..fc911ca22 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -28,10 +28,10 @@ library = [] [dependencies] cosmwasm-schema = { version = "1.4.0" } cw-utils = "1.0.1" -cw2 = { path = "../../packages/cw2", version = "1.1.2" } +cw2 = "1.1.2" cw4 = { path = "../../packages/cw4", version = "1.1.2" } cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cw-controllers = { path = "../../packages/controllers", version = "1.1.2" } +cw-controllers = "1.1.2" cw-storage-plus = "1.1.0" cosmwasm-std = { version = "1.4.0" } schemars = "0.8.15" diff --git a/packages/controllers/Cargo.toml b/packages/controllers/Cargo.toml deleted file mode 100644 index b2e199412..000000000 --- a/packages/controllers/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "cw-controllers" -version = "1.1.2" -authors = ["Ethan Frey "] -edition = "2021" -description = "Common controllers we can reuse in many contracts" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-schema = "1.4.0" -cosmwasm-std = "1.4.0" -cw-utils = "1.0.1" -cw-storage-plus = "1.1.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } diff --git a/packages/controllers/README.md b/packages/controllers/README.md deleted file mode 100644 index a5f4bd7df..000000000 --- a/packages/controllers/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# CW Controllers: Common controllers for many contracts - -This is a collection of "controllers" that we end up reimplementing in -many contracts. I use the word "controller" similar to the MVC framework -style, where it is an element that encapsulated business logic and data access. -We can also directly handle some `ExecuteMsg` and `QueryMsg` variants by -adding a sub-router to these controllers. - -This is the beginning of an experiment in code composition, and how best to -reuse code among multiple contracts. We have already seen some "extend" and -existing base contract (like `cw20-staking` extends `cw20-base`), but this -goes for smaller scale units. - -Supported controllers: - -* Admin (`UpdateAdmin` handler, `Admin` querier, set_admin and is_admin methods) diff --git a/packages/controllers/src/admin.rs b/packages/controllers/src/admin.rs deleted file mode 100644 index aac6ec8e8..000000000 --- a/packages/controllers/src/admin.rs +++ /dev/null @@ -1,184 +0,0 @@ -use schemars::JsonSchema; -use std::fmt; -use thiserror::Error; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, -}; -use cw_storage_plus::Item; - -// TODO: should the return values end up in utils, so eg. cw4 can import them as well as this module? -/// Returned from Admin.query_admin() -#[cw_serde] -pub struct AdminResponse { - pub admin: Option, -} - -/// Errors returned from Admin -#[derive(Error, Debug, PartialEq)] -pub enum AdminError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Caller is not admin")] - NotAdmin {}, -} - -// state/logic -pub struct Admin<'a>(Item<'a, Option>); - -// this is the core business logic we expose -impl<'a> Admin<'a> { - pub const fn new(namespace: &'a str) -> Self { - Admin(Item::new(namespace)) - } - - pub fn set(&self, deps: DepsMut, admin: Option) -> StdResult<()> { - self.0.save(deps.storage, &admin) - } - - pub fn get(&self, deps: Deps) -> StdResult> { - self.0.load(deps.storage) - } - - /// Returns Ok(true) if this is an admin, Ok(false) if not and an Error if - /// we hit an error with Api or Storage usage - pub fn is_admin(&self, deps: Deps, caller: &Addr) -> StdResult { - match self.0.load(deps.storage)? { - Some(owner) => Ok(caller == owner), - None => Ok(false), - } - } - - /// Like is_admin but returns AdminError::NotAdmin if not admin. - /// Helper for a nice one-line auth check. - pub fn assert_admin( - &self, - deps: Deps, - caller: &Addr, - ) -> Result<(), AdminError> { - if !self.is_admin(deps, caller)? { - Err(AdminError::NotAdmin {}) - } else { - Ok(()) - } - } - - pub fn execute_update_admin( - &self, - deps: DepsMut, - info: MessageInfo, - new_admin: Option, - ) -> Result, AdminError> - where - C: Clone + fmt::Debug + PartialEq + JsonSchema, - { - self.assert_admin(deps.as_ref(), &info.sender)?; - - let admin_str = match new_admin.as_ref() { - Some(admin) => admin.to_string(), - None => "None".to_string(), - }; - let attributes = vec![ - attr("action", "update_admin"), - attr("admin", admin_str), - attr("sender", info.sender), - ]; - - self.set(deps, new_admin)?; - - Ok(Response::new().add_attributes(attributes)) - } - - pub fn query_admin(&self, deps: Deps) -> StdResult { - let admin = self.get(deps)?.map(String::from); - Ok(AdminResponse { admin }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use cosmwasm_std::testing::{mock_dependencies, mock_info}; - use cosmwasm_std::Empty; - - #[test] - fn set_and_get_admin() { - let mut deps = mock_dependencies(); - let control = Admin::new("foo"); - - // initialize and check - let admin = Some(Addr::unchecked("admin")); - control.set(deps.as_mut(), admin.clone()).unwrap(); - let got = control.get(deps.as_ref()).unwrap(); - assert_eq!(admin, got); - - // clear it and check - control.set(deps.as_mut(), None).unwrap(); - let got = control.get(deps.as_ref()).unwrap(); - assert_eq!(None, got); - } - - #[test] - fn admin_checks() { - let mut deps = mock_dependencies(); - - let control = Admin::new("foo"); - let owner = Addr::unchecked("big boss"); - let imposter = Addr::unchecked("imposter"); - - // ensure checks proper with owner set - control.set(deps.as_mut(), Some(owner.clone())).unwrap(); - assert!(control.is_admin(deps.as_ref(), &owner).unwrap()); - assert!(!(control.is_admin(deps.as_ref(), &imposter).unwrap())); - control.assert_admin(deps.as_ref(), &owner).unwrap(); - let err = control.assert_admin(deps.as_ref(), &imposter).unwrap_err(); - assert_eq!(AdminError::NotAdmin {}, err); - - // ensure checks proper with owner None - control.set(deps.as_mut(), None).unwrap(); - assert!(!(control.is_admin(deps.as_ref(), &owner).unwrap())); - assert!(!(control.is_admin(deps.as_ref(), &imposter).unwrap())); - let err = control.assert_admin(deps.as_ref(), &owner).unwrap_err(); - assert_eq!(AdminError::NotAdmin {}, err); - let err = control.assert_admin(deps.as_ref(), &imposter).unwrap_err(); - assert_eq!(AdminError::NotAdmin {}, err); - } - - #[test] - fn test_execute_query() { - let mut deps = mock_dependencies(); - - // initial setup - let control = Admin::new("foo"); - let owner = Addr::unchecked("big boss"); - let imposter = Addr::unchecked("imposter"); - let friend = Addr::unchecked("buddy"); - control.set(deps.as_mut(), Some(owner.clone())).unwrap(); - - // query shows results - let res = control.query_admin(deps.as_ref()).unwrap(); - assert_eq!(Some(owner.to_string()), res.admin); - - // imposter cannot update - let info = mock_info(imposter.as_ref(), &[]); - let new_admin = Some(friend.clone()); - let err = control - .execute_update_admin::(deps.as_mut(), info, new_admin.clone()) - .unwrap_err(); - assert_eq!(AdminError::NotAdmin {}, err); - - // owner can update - let info = mock_info(owner.as_ref(), &[]); - let res = control - .execute_update_admin::(deps.as_mut(), info, new_admin) - .unwrap(); - assert_eq!(0, res.messages.len()); - - // query shows results - let res = control.query_admin(deps.as_ref()).unwrap(); - assert_eq!(Some(friend.to_string()), res.admin); - } -} diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs deleted file mode 100644 index 1c707e624..000000000 --- a/packages/controllers/src/claim.rs +++ /dev/null @@ -1,587 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, BlockInfo, CustomQuery, Deps, StdResult, Storage, Uint128}; -use cw_storage_plus::Map; -use cw_utils::Expiration; - -// TODO: pull into utils? -#[cw_serde] -pub struct ClaimsResponse { - pub claims: Vec, -} - -// TODO: pull into utils? -#[cw_serde] -pub struct Claim { - pub amount: Uint128, - pub release_at: Expiration, -} - -impl Claim { - pub fn new(amount: u128, released: Expiration) -> Self { - Claim { - amount: amount.into(), - release_at: released, - } - } -} - -// TODO: revisit design (split each claim on own key?) -pub struct Claims<'a>(Map<'a, &'a Addr, Vec>); - -impl<'a> Claims<'a> { - pub const fn new(storage_key: &'a str) -> Self { - Claims(Map::new(storage_key)) - } - - /// This creates a claim, such that the given address can claim an amount of tokens after - /// the release date. - pub fn create_claim( - &self, - storage: &mut dyn Storage, - addr: &Addr, - amount: Uint128, - release_at: Expiration, - ) -> StdResult<()> { - // add a claim to this user to get their tokens after the unbonding period - self.0.update(storage, addr, |old| -> StdResult<_> { - let mut claims = old.unwrap_or_default(); - claims.push(Claim { amount, release_at }); - Ok(claims) - })?; - Ok(()) - } - - /// This iterates over all mature claims for the address, and removes them, up to an optional cap. - /// it removes the finished claims and returns the total amount of tokens to be released. - pub fn claim_tokens( - &self, - storage: &mut dyn Storage, - addr: &Addr, - block: &BlockInfo, - cap: Option, - ) -> StdResult { - let mut to_send = Uint128::zero(); - self.0.update(storage, addr, |claim| -> StdResult<_> { - let (_send, waiting): (Vec<_>, _) = - claim.unwrap_or_default().into_iter().partition(|c| { - // if mature and we can pay fully, then include in _send - if c.release_at.is_expired(block) { - if let Some(limit) = cap { - if to_send + c.amount > limit { - return false; - } - } - // TODO: handle partial paying claims? - to_send += c.amount; - true - } else { - // not to send, leave in waiting and save again - false - } - }); - Ok(waiting) - })?; - Ok(to_send) - } - - pub fn query_claims( - &self, - deps: Deps, - address: &Addr, - ) -> StdResult { - let claims = self.0.may_load(deps.storage, address)?.unwrap_or_default(); - Ok(ClaimsResponse { claims }) - } -} - -#[cfg(test)] -mod test { - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env}, - Order, - }; - - use super::*; - const TEST_AMOUNT: u128 = 1000u128; - const TEST_EXPIRATION: Expiration = Expiration::AtHeight(10); - - #[test] - fn can_create_claim() { - let claim = Claim::new(TEST_AMOUNT, TEST_EXPIRATION); - assert_eq!(claim.amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(claim.release_at, TEST_EXPIRATION); - } - - #[test] - fn can_create_claims() { - let deps = mock_dependencies(); - let claims = Claims::new("claims"); - // Assert that claims creates a map and there are no keys in the map. - assert_eq!( - claims - .0 - .range_raw(&deps.storage, None, None, Order::Ascending) - .collect::>>() - .unwrap() - .len(), - 0 - ); - } - - #[test] - fn check_create_claim_updates_map() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - TEST_EXPIRATION, - ) - .unwrap(); - - // Assert that claims creates a map and there is one claim for the address. - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); - - // Adding another claim to same address, make sure that both claims are saved. - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - TEST_EXPIRATION, - ) - .unwrap(); - - // Assert that both claims exist for the address. - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); - assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[1].release_at, TEST_EXPIRATION); - - // Adding another claim to different address, make sure that other address only has one claim. - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr2"), - (TEST_AMOUNT + 100).into(), - TEST_EXPIRATION, - ) - .unwrap(); - - // Assert that both claims exist for the address. - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - let saved_claims_addr2 = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr2")) - .unwrap(); - assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims_addr2.len(), 1); - } - - #[test] - fn test_claim_tokens_with_no_claims() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &mock_env().block, - None, - ) - .unwrap(); - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::zero()); - assert_eq!(saved_claims.len(), 0); - } - - #[test] - fn test_claim_tokens_with_no_released_claims() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(100), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 0; - // the address has two claims however they are both not expired - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - None, - ) - .unwrap(); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::zero()); - assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); - } - - #[test] - fn test_claim_tokens_with_one_released_claim() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(100), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 20; - // the address has two claims and the first one can be released - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - None, - ) - .unwrap(); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(100)); - } - - #[test] - fn test_claim_tokens_with_all_released_claims() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(100), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 1000; - // the address has two claims and both can be released - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - None, - ) - .unwrap(); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::from(TEST_AMOUNT + TEST_AMOUNT + 100)); - assert_eq!(saved_claims.len(), 0); - } - - #[test] - fn test_claim_tokens_with_zero_cap() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(100), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 1000; - - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - Some(Uint128::zero()), - ) - .unwrap(); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::zero()); - assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); - } - - #[test] - fn test_claim_tokens_with_cap_greater_than_pending_claims() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(100), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 1000; - - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - Some(Uint128::from(2100u128)), - ) - .unwrap(); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - - assert_eq!(amount, Uint128::from(TEST_AMOUNT + TEST_AMOUNT + 100)); - assert_eq!(saved_claims.len(), 0); - } - - #[test] - fn test_claim_tokens_with_cap_only_one_claim_released() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(5), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 1000; - // the address has two claims and the first one can be released - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - Some((TEST_AMOUNT + 50).into()), - ) - .unwrap(); - assert_eq!(amount, Uint128::from(TEST_AMOUNT)); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - assert_eq!(saved_claims.len(), 1); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - } - - #[test] - fn test_claim_tokens_with_cap_too_low_no_claims_released() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - TEST_AMOUNT.into(), - Expiration::AtHeight(5), - ) - .unwrap(); - - let mut env = mock_env(); - env.block.height = 1000; - // the address has two claims and the first one can be released - let amount = claims - .claim_tokens( - deps.as_mut().storage, - &Addr::unchecked("addr"), - &env.block, - Some((TEST_AMOUNT - 50).into()), - ) - .unwrap(); - assert_eq!(amount, Uint128::zero()); - - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - assert_eq!(saved_claims.len(), 2); - assert_eq!(saved_claims[0].amount, Uint128::from(TEST_AMOUNT + 100)); - assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); - assert_eq!(saved_claims[1].amount, Uint128::from(TEST_AMOUNT)); - assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(5)); - } - - #[test] - fn test_query_claims_returns_correct_claims() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - let queried_claims = claims - .query_claims(deps.as_ref(), &Addr::unchecked("addr")) - .unwrap(); - let saved_claims = claims - .0 - .load(deps.as_mut().storage, &Addr::unchecked("addr")) - .unwrap(); - assert_eq!(queried_claims.claims, saved_claims); - } - - #[test] - fn test_query_claims_returns_empty_for_non_existent_user() { - let mut deps = mock_dependencies(); - let claims = Claims::new("claims"); - - claims - .create_claim( - deps.as_mut().storage, - &Addr::unchecked("addr"), - (TEST_AMOUNT + 100).into(), - Expiration::AtHeight(10), - ) - .unwrap(); - - let queried_claims = claims - .query_claims(deps.as_ref(), &Addr::unchecked("addr2")) - .unwrap(); - - assert_eq!(queried_claims.claims.len(), 0); - } -} diff --git a/packages/controllers/src/hooks.rs b/packages/controllers/src/hooks.rs deleted file mode 100644 index fca49fbb4..000000000 --- a/packages/controllers/src/hooks.rs +++ /dev/null @@ -1,131 +0,0 @@ -use schemars::JsonSchema; -use std::fmt; -use thiserror::Error; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - attr, Addr, CustomQuery, Deps, DepsMut, MessageInfo, Response, StdError, StdResult, Storage, - SubMsg, -}; -use cw_storage_plus::Item; - -use crate::admin::{Admin, AdminError}; - -// this is copied from cw4 -// TODO: pull into utils as common dep -#[cw_serde] -pub struct HooksResponse { - pub hooks: Vec, -} - -#[derive(Error, Debug, PartialEq)] -pub enum HookError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Admin(#[from] AdminError), - - #[error("Given address already registered as a hook")] - HookAlreadyRegistered {}, - - #[error("Given address not registered as a hook")] - HookNotRegistered {}, -} - -// store all hook addresses in one item. We cannot have many of them before the contract becomes unusable anyway. -pub struct Hooks<'a>(Item<'a, Vec>); - -impl<'a> Hooks<'a> { - pub const fn new(storage_key: &'a str) -> Self { - Hooks(Item::new(storage_key)) - } - - pub fn add_hook(&self, storage: &mut dyn Storage, addr: Addr) -> Result<(), HookError> { - let mut hooks = self.0.may_load(storage)?.unwrap_or_default(); - if !hooks.iter().any(|h| h == addr) { - hooks.push(addr); - } else { - return Err(HookError::HookAlreadyRegistered {}); - } - Ok(self.0.save(storage, &hooks)?) - } - - pub fn remove_hook(&self, storage: &mut dyn Storage, addr: Addr) -> Result<(), HookError> { - let mut hooks = self.0.load(storage)?; - if let Some(p) = hooks.iter().position(|x| x == addr) { - hooks.remove(p); - } else { - return Err(HookError::HookNotRegistered {}); - } - Ok(self.0.save(storage, &hooks)?) - } - - pub fn prepare_hooks StdResult>( - &self, - storage: &dyn Storage, - prep: F, - ) -> StdResult> { - self.0 - .may_load(storage)? - .unwrap_or_default() - .into_iter() - .map(prep) - .collect() - } - - pub fn execute_add_hook( - &self, - admin: &Admin, - deps: DepsMut, - info: MessageInfo, - addr: Addr, - ) -> Result, HookError> - where - C: Clone + fmt::Debug + PartialEq + JsonSchema, - { - admin.assert_admin(deps.as_ref(), &info.sender)?; - self.add_hook(deps.storage, addr.clone())?; - - let attributes = vec![ - attr("action", "add_hook"), - attr("hook", addr), - attr("sender", info.sender), - ]; - Ok(Response::new().add_attributes(attributes)) - } - - pub fn execute_remove_hook( - &self, - admin: &Admin, - deps: DepsMut, - info: MessageInfo, - addr: Addr, - ) -> Result, HookError> - where - C: Clone + fmt::Debug + PartialEq + JsonSchema, - { - admin.assert_admin(deps.as_ref(), &info.sender)?; - self.remove_hook(deps.storage, addr.clone())?; - - let attributes = vec![ - attr("action", "remove_hook"), - attr("hook", addr), - attr("sender", info.sender), - ]; - Ok(Response::new().add_attributes(attributes)) - } - - pub fn query_hooks(&self, deps: Deps) -> StdResult { - let hooks = self.0.may_load(deps.storage)?.unwrap_or_default(); - let hooks = hooks.into_iter().map(String::from).collect(); - Ok(HooksResponse { hooks }) - } - - // Return true if hook is in hooks - pub fn query_hook(&self, deps: Deps, hook: String) -> StdResult { - Ok(self.query_hooks(deps)?.hooks.into_iter().any(|h| h == hook)) - } -} - -// TODO: add test coverage diff --git a/packages/controllers/src/lib.rs b/packages/controllers/src/lib.rs deleted file mode 100644 index 4d17478d6..000000000 --- a/packages/controllers/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -/*! -This is a collection of "controllers" that we end up reimplementing in -many contracts. I use the word "controller" similar to the MVC framework -style, where it is an element that encapsulated business logic and data access. -We can also directly handle some `ExecuteMsg` and `QueryMsg` variants by -adding a sub-router to these controllers. - -This is the beginning of an experiment in code composition, and how best to -reuse code among multiple contracts. We have already seen some "extend" and -existing base contract (like `cw20-staking` extends `cw20-base`), but this -goes for smaller scale units. - -Supported controllers: - -* Admin (`UpdateAdmin` handler, `Admin` querier, set_admin and is_admin methods) -*/ -mod admin; -mod claim; -mod hooks; - -pub use admin::{Admin, AdminError, AdminResponse}; -pub use claim::{Claim, Claims, ClaimsResponse}; -pub use hooks::{HookError, Hooks, HooksResponse}; diff --git a/packages/cw2/.cargo/config b/packages/cw2/.cargo/config deleted file mode 100644 index e82e5693f..000000000 --- a/packages/cw2/.cargo/config +++ /dev/null @@ -1,3 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" diff --git a/packages/cw2/Cargo.toml b/packages/cw2/Cargo.toml deleted file mode 100644 index 5e7804005..000000000 --- a/packages/cw2/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "cw2" -version = "1.1.2" -authors = ["Ethan Frey "] -edition = "2021" -description = "Definition and types for the CosmWasm-2 interface" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" - -[dependencies] -cosmwasm-schema = "1.4.0" -cosmwasm-std = { version = "1.4.0", default-features = false } -cw-storage-plus = "1.1.0" -schemars = "0.8.15" -semver = { version = "1.0.20", default-features = false } -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = "1.0.49" diff --git a/packages/cw2/README.md b/packages/cw2/README.md deleted file mode 100644 index bfbb82eae..000000000 --- a/packages/cw2/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# CW2 Spec: Contract Info - -Most of the CW* specs are focused on the *public interfaces* -of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. -However, when we wish to migrate or inspect smart contract info, -we need some form of smart contract information embedded on state. - -This is where CW2 comes in. It specifies a special Item to -be stored on disk by all contracts on `instantiate`. - -`ContractInfo` must be stored under the `"contract_info"` key which translates -to `"636F6E74726163745F696E666F"` in hex format. -Since the state is well defined, we do not need to support any "smart queries". -We do provide a helper to construct a "raw query" to read the ContractInfo -of any CW2-compliant contract. - -You can query using: -```shell -wasmd query wasm contract-state raw [contract_addr] 636F6E74726163745F696E666F --node $RPC -``` - -When the `migrate` function is called, then the new contract -can read that data and see if this is an expected contract we can -migrate from. And also contain extra version information if we -support multiple migrate paths. -This crate provides an `ensure_from_older_version` helper that -handles this. - -### Data structures - -**Required** - -All CW2-compliant contracts must store the following data: - -* key: `contract_info` -* data: Json-serialized `ContractVersion` - -```rust -pub struct ContractVersion { - /// contract is a globally unique identifier for the contract. - /// it should build off standard namespacing for whichever language it is in, - /// and prefix it with the registry we use. - /// For rust we prefix with `crates.io:`, to give us eg. `crates.io:cw20-base` - pub contract: String, - /// version is any string that this implementation knows. It may be simple counter "1", "2". - /// or semantic version on release tags "v0.7.0", or some custom feature flag list. - /// the only code that needs to understand the version parsing is code that knows how to - /// migrate from the given contract (and is tied to it's implementation somehow) - pub version: String, -} -``` - -Thus, an serialized example may looks like: - -```json -{ - "contract": "crates.io:cw20-base", - "version": "v0.1.0" -} -``` diff --git a/packages/cw2/src/lib.rs b/packages/cw2/src/lib.rs deleted file mode 100644 index 808008afb..000000000 --- a/packages/cw2/src/lib.rs +++ /dev/null @@ -1,193 +0,0 @@ -/*! -Most of the CW* specs are focused on the *public interfaces* -of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`. -However, when we wish to migrate or inspect smart contract info, -we need some form of smart contract information embedded on state. - -This is where CW2 comes in. It specifies a special Item to -be stored on disk by all contracts on `instantiate`. - -`ContractInfo` must be stored under the `"contract_info"` key which translates -to `"636F6E74726163745F696E666F"` in hex format. -Since the state is well defined, we do not need to support any "smart queries". -We do provide a helper to construct a "raw query" to read the ContractInfo -of any CW2-compliant contract. - -For more information on this specification, please check out the -[README](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw2/README.md). -*/ - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - CustomQuery, QuerierWrapper, QueryRequest, StdError, StdResult, Storage, WasmQuery, -}; -use cw_storage_plus::Item; -use thiserror::Error; - -mod migrate; - -pub use migrate::ensure_from_older_version; - -pub const CONTRACT: Item = Item::new("contract_info"); - -#[cw_serde] -pub struct ContractVersion { - /// contract is the crate name of the implementing contract, eg. `crate:cw20-base` - /// we will use other prefixes for other languages, and their standard global namespacing - pub contract: String, - /// version is any string that this implementation knows. It may be simple counter "1", "2". - /// or semantic version on release tags "v0.7.0", or some custom feature flag list. - /// the only code that needs to understand the version parsing is code that knows how to - /// migrate from the given contract (and is tied to it's implementation somehow) - pub version: String, -} - -#[derive(Error, Debug, PartialEq)] -pub enum VersionError { - #[error(transparent)] - Std(#[from] StdError), - - #[error("Contract version info not found")] - NotFound, - - #[error("Wrong contract: expecting `{expected}`, found `{found}`")] - WrongContract { expected: String, found: String }, - - #[error("Wrong contract version: expecting `{expected}`, found `{found}`")] - WrongVersion { expected: String, found: String }, -} - -/// Assert that the stored contract version info matches the given value. -/// This is useful during migrations, for making sure that the correct contract -/// is being migrated, and it's being migrated from the correct version. -pub fn assert_contract_version( - storage: &dyn Storage, - expected_contract: &str, - expected_version: &str, -) -> Result<(), VersionError> { - let ContractVersion { contract, version } = match CONTRACT.may_load(storage)? { - Some(contract) => contract, - None => return Err(VersionError::NotFound), - }; - - if contract != expected_contract { - return Err(VersionError::WrongContract { - expected: expected_contract.into(), - found: contract, - }); - } - - if version != expected_version { - return Err(VersionError::WrongVersion { - expected: expected_version.into(), - found: version, - }); - } - - Ok(()) -} - -/// get_contract_version can be use in migrate to read the previous version of this contract -pub fn get_contract_version(store: &dyn Storage) -> StdResult { - CONTRACT.load(store) -} - -/// set_contract_version should be used in instantiate to store the original version, and after a successful -/// migrate to update it -pub fn set_contract_version, U: Into>( - store: &mut dyn Storage, - name: T, - version: U, -) -> StdResult<()> { - let val = ContractVersion { - contract: name.into(), - version: version.into(), - }; - CONTRACT.save(store, &val) -} - -/// This will make a raw_query to another contract to determine the current version it -/// claims to be. This should not be trusted, but could be used as a quick filter -/// if the other contract exists and claims to be a cw20-base contract for example. -/// (Note: you usually want to require *interfaces* not *implementations* of the -/// contracts you compose with, so be careful of overuse) -pub fn query_contract_info( - querier: &QuerierWrapper, - contract_addr: T, -) -> StdResult -where - T: Into, - CQ: CustomQuery, -{ - let req = QueryRequest::Wasm(WasmQuery::Raw { - contract_addr: contract_addr.into(), - key: CONTRACT.as_slice().into(), - }); - querier.query(&req) -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn get_and_set_work() { - let mut store = MockStorage::new(); - - // error if not set - assert!(get_contract_version(&store).is_err()); - - // set and get - let contract_name = "crate:cw20-base"; - let contract_version = "0.2.0"; - set_contract_version(&mut store, contract_name, contract_version).unwrap(); - - let loaded = get_contract_version(&store).unwrap(); - let expected = ContractVersion { - contract: contract_name.to_string(), - version: contract_version.to_string(), - }; - assert_eq!(expected, loaded); - } - - #[test] - fn assert_work() { - let mut store = MockStorage::new(); - - const EXPECTED_CONTRACT: &str = "crate:mars-red-bank"; - const EXPECTED_VERSION: &str = "1.0.0"; - - // error if contract version is not set - let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); - assert_eq!(err, VersionError::NotFound); - - // wrong contract name - let wrong_contract = "crate:cw20-base"; - set_contract_version(&mut store, wrong_contract, EXPECTED_VERSION).unwrap(); - let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); - assert_eq!( - err, - VersionError::WrongContract { - expected: EXPECTED_CONTRACT.into(), - found: wrong_contract.into() - }, - ); - - // wrong contract version - let wrong_version = "8.8.8"; - set_contract_version(&mut store, EXPECTED_CONTRACT, wrong_version).unwrap(); - let err = assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap_err(); - assert_eq!( - err, - VersionError::WrongVersion { - expected: EXPECTED_VERSION.into(), - found: wrong_version.into() - }, - ); - - // correct name and version - set_contract_version(&mut store, EXPECTED_CONTRACT, EXPECTED_VERSION).unwrap(); - assert!(assert_contract_version(&store, EXPECTED_CONTRACT, EXPECTED_VERSION).is_ok()); - } -} diff --git a/packages/cw2/src/migrate.rs b/packages/cw2/src/migrate.rs deleted file mode 100644 index c92ce2152..000000000 --- a/packages/cw2/src/migrate.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::{get_contract_version, set_contract_version}; -use cosmwasm_std::{StdError, StdResult, Storage}; -use semver::Version; - -/// This function not only validates that the right contract and version can be migrated, but also -/// updates the contract version from the original (stored) version to the new version. -/// It returns the original version for the convenience of doing external checks. -pub fn ensure_from_older_version( - storage: &mut dyn Storage, - name: &str, - new_version: &str, -) -> StdResult { - let version: Version = new_version.parse().map_err(from_semver)?; - let stored = get_contract_version(storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - if name != stored.contract { - let msg = format!("Cannot migrate from {} to {}", stored.contract, name); - return Err(StdError::generic_err(msg)); - } - - if storage_version > version { - let msg = format!( - "Cannot migrate from newer version ({}) to older ({})", - stored.version, new_version - ); - return Err(StdError::generic_err(msg)); - } - if storage_version < version { - // we don't need to save anything if migrating from the same version - set_contract_version(storage, name, new_version)?; - } - - Ok(storage_version) -} - -fn from_semver(err: semver::Error) -> StdError { - StdError::generic_err(format!("Semver: {err}")) -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::MockStorage; - - #[test] - fn accepts_identical_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); - // ensure this matches - ensure_from_older_version(&mut storage, "demo", "0.1.2").unwrap(); - } - - #[test] - fn accepts_and_updates_on_newer_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.4.0").unwrap(); - // ensure this matches - let original_version = ensure_from_older_version(&mut storage, "demo", "0.4.2").unwrap(); - - // check the original version is returned - assert_eq!(original_version.to_string(), "0.4.0".to_string()); - - // check the version is updated - let stored = get_contract_version(&storage).unwrap(); - assert_eq!(stored.contract, "demo".to_string()); - assert_eq!(stored.version, "0.4.2".to_string()); - } - - #[test] - fn errors_on_name_mismatch() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.1.2").unwrap(); - // ensure this matches - let err = ensure_from_older_version(&mut storage, "cw20-base", "0.1.2").unwrap_err(); - assert!(err.to_string().contains("cw20-base"), "{}", err); - assert!(err.to_string().contains("demo"), "{}", err); - } - - #[test] - fn errors_on_older_version() { - let mut storage = MockStorage::new(); - set_contract_version(&mut storage, "demo", "0.10.2").unwrap(); - // ensure this matches - let err = ensure_from_older_version(&mut storage, "demo", "0.9.7").unwrap_err(); - assert!(err.to_string().contains("0.10.2"), "{}", err); - assert!(err.to_string().contains("0.9.7"), "{}", err); - } - - #[test] - fn errors_on_broken_version() { - let mut storage = MockStorage::new(); - let err = ensure_from_older_version(&mut storage, "demo", "0.a.7").unwrap_err(); - assert!( - err.to_string().contains("unexpected character 'a'"), - "{}", - err - ); - } -} From 409c7a0ce409da196a35ed9b49dbe8fe2adec5d9 Mon Sep 17 00:00:00 2001 From: Tomasz Kulik Date: Thu, 15 Feb 2024 09:41:35 +0100 Subject: [PATCH 602/631] chore: Update publish script --- scripts/publish.sh | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index 3a210db91..c7b545c24 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -13,9 +13,8 @@ then exit 1 fi -# these are imported by other packages -BASE_PACKAGES="cw2" -ALL_PACKAGES="controllers cw1 cw3 cw4 cw20" +# These are imported by other packages +ALL_PACKAGES="cw1 cw3 cw4 cw20" # This is imported by cw3-fixed-multisig, which is imported by cw3-flex-multisig # need to make a separate category to remove race conditions @@ -26,18 +25,6 @@ ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-ics20" SLEEP_TIME=30 -for pack in $BASE_PACKAGES; do - ( - cd "packages/$pack" - echo "Publishing $pack" - cargo publish - ) -done - -# wait for these to be processed on crates.io -echo "Waiting for publishing base packages" -sleep $SLEEP_TIME - for pack in $ALL_PACKAGES; do ( cd "packages/$pack" From f40c2c07465e309a01d2d881e5c0346ac4825ca2 Mon Sep 17 00:00:00 2001 From: Tomasz Kulik Date: Thu, 15 Feb 2024 09:47:16 +0100 Subject: [PATCH 603/631] docs: Update README --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 428c35af8..236dca30a 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,10 @@ | Specification | Crates.io | Docs | Coverage | | ------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | cw1 | [![cw1 on crates.io](https://img.shields.io/crates/v/cw1.svg)](https://crates.io/crates/cw1) | [![Docs](https://docs.rs/cw1/badge.svg)](https://docs.rs/cw1) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| cw2 | [![cw2 on crates.io](https://img.shields.io/crates/v/cw2.svg)](https://crates.io/crates/cw2) | [![Docs](https://docs.rs/cw2/badge.svg)](https://docs.rs/cw2) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw3 | [![cw3 on crates.io](https://img.shields.io/crates/v/cw3.svg)](https://crates.io/crates/cw3) | [![Docs](https://docs.rs/cw3/badge.svg)](https://docs.rs/cw3) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -| Utilities | Crates.io | Docs | Coverage | -| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| cw-controllers | [![cw-controllers on crates.io](https://img.shields.io/crates/v/cw-controllers.svg)](https://crates.io/crates/cw-controllers) | [![Docs](https://docs.rs/cw-controllers/badge.svg)](https://docs.rs/cw-controllers) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | Contracts | Download | Docs | Coverage | | ------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | @@ -25,6 +21,8 @@ | cw20-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20-ics20 | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | +Note: `cw2` and `controllers` have been moved to the [`cw-minus` repo](https://github.com/CosmWasm/cw-minus) and can be followed there. + Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be followed there. From ddd180dd34df3681da61a6554d53f3f06fe8a256 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Thu, 29 Feb 2024 22:10:20 +0100 Subject: [PATCH 604/631] set up workspace inheritance --- Cargo.toml | 29 ++++++++++++++++++++ contracts/cw1-subkeys/Cargo.toml | 26 +++++++++--------- contracts/cw1-whitelist/Cargo.toml | 20 +++++++------- contracts/cw20-base/Cargo.toml | 25 +++++++++--------- contracts/cw20-ics20/Cargo.toml | 25 +++++++++--------- contracts/cw3-fixed-multisig/Cargo.toml | 27 +++++++++---------- contracts/cw3-flex-multisig/Cargo.toml | 35 +++++++++++-------------- contracts/cw4-group/Cargo.toml | 24 ++++++++--------- contracts/cw4-stake/Cargo.toml | 26 +++++++++--------- packages/cw1/Cargo.toml | 8 +++--- packages/cw20/Cargo.toml | 14 +++++----- packages/cw3/Cargo.toml | 16 +++++------ packages/cw4/Cargo.toml | 10 +++---- 13 files changed, 151 insertions(+), 134 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df1b7252f..b326e944b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,35 @@ members = ["packages/*", "contracts/*"] # Resolver has to be set explicitely in workspaces, see https://github.com/rust-lang/cargo/issues/9956 resolver = "2" +[workspace.package] +version = "1.1.2" + +[workspace.dependencies] +cosmwasm-schema = "1.4" +cosmwasm-std = "1.4" +cw2 = "1.1" +cw-controllers = "1.1" +cw-multi-test = "0.16.5" +cw-storage-plus = "1.1" +cw-utils = "1" +schemars = "0.8.15" +semver = "1" +serde = { version = "1.0.188", default-features = false, features = ["derive"] } +thiserror = "1.0.4" + +cw1 = { path = "packages/cw1", version = "1.1.2" } +cw1-whitelist = { path = "contracts/cw1-whitelist", version = "1.1.2", features = [ + "library", +] } +cw20 = { path = "packages/cw20", version = "1.1.2" } +cw20-base = { path = "contracts/cw20-base", version = "1.1.2", features = ["library"] } +cw3 = { path = "packages/cw3", version = "1.1.2" } +cw3-fixed-multisig = { path = "contracts/cw3-fixed-multisig", version = "1.1.2", features = [ + "library", +] } +cw4 = { path = "packages/cw4", version = "1.1.2" } +cw4-group = { path = "contracts/cw4-group", version = "1.1.2" } + [profile.release.package.cw1-subkeys] codegen-units = 1 incremental = false diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 76c335697..9ecb51476 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -19,22 +19,20 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.2" } -cw2 = "1.1.2" -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.2", features = [ - "library", -] } -cosmwasm-std = { version = "1.4.0", features = ["staking"] } -cw-storage-plus = "1.1.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = "1.0.49" -semver = "1" +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw1 = { workspace = true } +cw2 = { workspace = true } +cw1-whitelist = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cw-storage-plus = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +semver = { workspace = true } [dev-dependencies] -cw1-whitelist = { path = "../cw1-whitelist", version = "1.1.2", features = [ +cw1-whitelist = { workspace = true, features = [ "library", "test-utils", ] } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 9089808d3..c9f0d6c3e 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -19,18 +19,18 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw1 = { path = "../../packages/cw1", version = "1.1.2" } -cw2 = "1.1.2" -cosmwasm-std = { version = "1.4.0", features = ["staking"] } -cw-storage-plus = "1.1.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw1 = { workspace = true } +cw2 = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cw-storage-plus = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = "0.16.5" +cw-multi-test = { workspace = true } derivative = "2" diff --git a/contracts/cw20-base/Cargo.toml b/contracts/cw20-base/Cargo.toml index e35a05d56..e3cffc329 100644 --- a/contracts/cw20-base/Cargo.toml +++ b/contracts/cw20-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-base" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Basic implementation of a CosmWasm-20 compliant token" @@ -13,21 +13,20 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw2 = "1.1.2" -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cw-storage-plus = "1.1.0" -cosmwasm-std = { version = "1.4.0" } -schemars = "0.8.15" -semver = "1" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw2 = { workspace = true } +cw20 = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +semver = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] -cw-multi-test = "0.16.5" -cw-utils = "1.0.1" +cw-multi-test = { workspace = true } +cw-utils = { workspace = true } diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index a73654450..6f73e6a74 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20-ics20" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain" @@ -13,19 +13,18 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all init/handle/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw2 = "1.1.2" -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cosmwasm-std = { version = "1.4.0", features = ["stargate"] } -cw-storage-plus = "1.1.0" -cw-controllers = "1.1.2" -schemars = "0.8.15" -semver = "1" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw20 = { workspace = true } +cosmwasm-std = { workspace = true, features = ["stargate"] } +cw-storage-plus = { workspace = true } +cw-controllers = { workspace = true } +schemars = { workspace = true } +semver = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index 430e65f93..e6463be6c 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-fixed-multisig" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with an fixed group multisig" @@ -13,22 +13,21 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw2 = "1.1.2" -cw3 = { path = "../../packages/cw3", version = "1.1.2" } -cw-storage-plus = "1.1.0" -cosmwasm-std = { version = "1.4.0" } -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw3 = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cw20-base = { path = "../cw20-base", version = "1.1.2", features = ["library"] } -cw-multi-test = "0.16.1" +cw20 = { workspace = true } +cw20-base = { workspace = true } +cw-multi-test = { workspace = true } diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 76d334397..0f062b690 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3-flex-multisig" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" @@ -13,27 +13,24 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw2 = "1.1.2" -cw3 = { path = "../../packages/cw3", version = "1.1.2" } -cw3-fixed-multisig = { path = "../cw3-fixed-multisig", version = "1.1.2", features = [ - "library", -] } -cw4 = { path = "../../packages/cw4", version = "1.1.2" } -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cw-storage-plus = "1.1.0" -cosmwasm-std = { version = "1.4.0" } -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw3 = { workspace = true } +cw3-fixed-multisig = { workspace = true } +cw4 = { workspace = true } +cw20 = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] -cw4-group = { path = "../cw4-group", version = "1.1.2" } -cw-multi-test = "0.16.5" -cw20-base = { path = "../cw20-base", version = "1.1.2" } +cw4-group = { workspace = true } +cw-multi-test = { workspace = true } +cw20-base = { workspace = true } diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index bdfecff9b..9cb692c02 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-group" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " @@ -20,19 +20,17 @@ exclude = [ crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw2 = "1.1.2" -cw4 = { path = "../../packages/cw4", version = "1.1.2" } -cw-controllers = "1.1.2" -cw-storage-plus = "1.1.0" -cosmwasm-std = { version = "1.4.0" } -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw4 = { workspace = true } +cw-controllers = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index fc911ca22..006c83695 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4-stake" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "CW4 implementation of group based on staked tokens" @@ -20,20 +20,18 @@ exclude = [ crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cosmwasm-schema = { version = "1.4.0" } -cw-utils = "1.0.1" -cw2 = "1.1.2" -cw4 = { path = "../../packages/cw4", version = "1.1.2" } -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cw-controllers = "1.1.2" -cw-storage-plus = "1.1.0" -cosmwasm-std = { version = "1.4.0" } -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw4 = { workspace = true } +cw20 = { workspace = true } +cw-controllers = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index 3b08d1539..f9aea5555 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "1.4.0" -cosmwasm-std = "1.4.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } diff --git a/packages/cw20/Cargo.toml b/packages/cw20/Cargo.toml index ad89d4009..0df12cbb9 100644 --- a/packages/cw20/Cargo.toml +++ b/packages/cw20/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw20" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-20 interface" @@ -9,11 +9,11 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = "1.0.1" -cosmwasm-schema = "1.4.0" -cosmwasm-std = "1.4.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } +cw-utils = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } [dev-dependencies] -cosmwasm-schema = { version = "1.4.0" } +cosmwasm-schema = { workspace = true } diff --git a/packages/cw3/Cargo.toml b/packages/cw3/Cargo.toml index 2ac6bc2cd..81a33992c 100644 --- a/packages/cw3/Cargo.toml +++ b/packages/cw3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw3" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-3 Interface: On-Chain MultiSig/Voting contracts" @@ -9,10 +9,10 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-utils = "1.0.1" -cw20 = { path = "../../packages/cw20", version = "1.1.2" } -cosmwasm-schema = "1.4.0" -cosmwasm-std = "1.4.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.49" } +cw-utils = { workspace = true } +cw20 = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index b3d3c26fd..32fc5d53a 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -9,8 +9,8 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cw-storage-plus = "1.1.0" -cosmwasm-schema = "1.4.0" -cosmwasm-std = "1.4.0" -schemars = "0.8.15" -serde = { version = "1.0.188", default-features = false, features = ["derive"] } +cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } From 5e794c23ca3e9de8438498b0cbf7cec9d947271a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Thu, 29 Feb 2024 22:10:55 +0100 Subject: [PATCH 605/631] update everything to cw 1.5 --- Cargo.lock | 336 +++++++++++------- Cargo.toml | 8 +- contracts/cw1-subkeys/src/contract.rs | 18 +- contracts/cw1-whitelist/src/contract.rs | 10 +- .../cw1-whitelist/src/integration_tests.rs | 8 +- contracts/cw20-base/src/allowances.rs | 2 +- contracts/cw20-base/src/contract.rs | 36 +- contracts/cw20-base/src/enumerable.rs | 8 +- contracts/cw20-ics20/src/contract.rs | 85 +++-- contracts/cw20-ics20/src/ibc.rs | 64 ++-- contracts/cw20-ics20/src/migrations.rs | 4 +- contracts/cw20-ics20/src/test_helpers.rs | 2 +- contracts/cw3-fixed-multisig/src/contract.rs | 29 +- .../src/integration_tests.rs | 4 +- contracts/cw3-flex-multisig/src/contract.rs | 24 +- contracts/cw4-group/src/contract.rs | 14 +- contracts/cw4-group/src/helpers.rs | 4 +- contracts/cw4-group/src/tests.rs | 14 +- contracts/cw4-stake/src/contract.rs | 46 +-- packages/cw1/src/helpers.rs | 4 +- packages/cw20/src/helpers.rs | 6 +- packages/cw20/src/receiver.rs | 8 +- packages/cw3/src/deposit.rs | 6 +- packages/cw3/src/helpers.rs | 4 +- packages/cw3/src/msg.rs | 6 +- packages/cw3/src/proposal.rs | 2 +- packages/cw4/Cargo.toml | 2 +- packages/cw4/src/helpers.rs | 6 +- packages/cw4/src/hook.rs | 8 +- 29 files changed, 440 insertions(+), 328 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4394950e0..61b0d5c35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.69" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "assert_matches" @@ -39,9 +39,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -49,6 +49,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "block-buffer" version = "0.9.0" @@ -60,30 +66,30 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "bnum" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cfg-if" @@ -93,17 +99,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca101fbf2f76723711a30ea3771ef312ec3ec254ad021b237871ed802f9f175" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "ecdsa 0.16.9", "ed25519-zebra", "k256 0.13.1", "rand_core 0.6.4", @@ -112,18 +119,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c73d2dd292f60e42849d2b07c03d809cf31e128a4299a805abd6d24553bcaaf5" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce34a08020433989af5cc470104f6bd22134320fe0221bd8aeb919fd5ec92d5" +checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -134,9 +141,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96694ec781a7dd6dea1f968a2529ade009c21ad999c88b5f53d6cc495b3b96f7" +checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" dependencies = [ "proc-macro2", "quote", @@ -145,11 +152,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a44d3f9c25b2f864737c6605a98f2e4675d53fd8bbc7cf4d7c02475661a793d" +checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" dependencies = [ "base64", + "bech32", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -159,15 +167,16 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", - "sha2 0.10.6", + "sha2 0.10.8", + "static_assertions", "thiserror", ] [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -186,9 +195,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -245,19 +254,39 @@ dependencies = [ "cw-storage-plus", "cw-utils", "derivative", - "itertools", + "itertools 0.10.5", "k256 0.11.6", - "prost", + "prost 0.9.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-multi-test" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" +dependencies = [ + "anyhow", + "bech32", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "derivative", + "itertools 0.12.1", + "prost 0.12.3", "schemars", "serde", + "sha2 0.10.8", "thiserror", ] [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -314,7 +343,7 @@ dependencies = [ "assert_matches", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-storage-plus", "cw-utils", "cw1", @@ -357,7 +386,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -404,7 +433,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -422,7 +451,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -523,11 +552,11 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -535,9 +564,19 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "easy-addr" +version = "1.1.2" +dependencies = [ + "cosmwasm-std", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "ecdsa" @@ -553,16 +592,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.8", - "digest 0.10.6", - "elliptic-curve 0.13.5", + "digest 0.10.7", + "elliptic-curve 0.13.8", "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -582,9 +621,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -595,7 +634,7 @@ dependencies = [ "base16ct 0.1.1", "crypto-bigint 0.4.9", "der 0.6.1", - "digest 0.10.6", + "digest 0.10.7", "ff 0.12.1", "generic-array", "group 0.12.1", @@ -608,19 +647,19 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", - "digest 0.10.6", + "crypto-bigint 0.5.5", + "digest 0.10.7", "ff 0.13.0", "generic-array", "group 0.13.0", "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1 0.7.1", + "sec1 0.7.3", "subtle", "zeroize", ] @@ -653,9 +692,9 @@ checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -664,9 +703,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -716,7 +755,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -728,11 +767,29 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "k256" @@ -743,7 +800,7 @@ dependencies = [ "cfg-if", "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2 0.10.6", + "sha2 0.10.8", ] [[package]] @@ -753,24 +810,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.7", - "elliptic-curve 0.13.5", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", - "sha2 0.10.6", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", ] [[package]] name = "libc" -version = "0.2.139" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "once_cell" -version = "1.17.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -795,14 +852,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.2", + "spki 0.7.3", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -814,7 +871,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.9.0", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", ] [[package]] @@ -824,17 +891,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -877,15 +957,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -895,9 +975,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -921,9 +1001,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", "der 0.7.8", @@ -935,37 +1015,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.52", ] [[package]] @@ -981,9 +1061,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -1005,13 +1085,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -1020,17 +1100,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -1046,19 +1126,25 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der 0.7.8", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -1073,9 +1159,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -1084,35 +1170,35 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.52", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version_check" @@ -1128,6 +1214,6 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "zeroize" -version = "1.5.7" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index b326e944b..4384fd839 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ resolver = "2" version = "1.1.2" [workspace.dependencies] -cosmwasm-schema = "1.4" -cosmwasm-std = "1.4" +cosmwasm-schema = "1.5" +cosmwasm-std = "1.5" cw2 = "1.1" cw-controllers = "1.1" -cw-multi-test = "0.16.5" -cw-storage-plus = "1.1" +cw-multi-test = "0.20" +cw-storage-plus = "1.2" cw-utils = "1" schemars = "0.8.15" semver = "1" diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index 3a88caec2..75c59be5a 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -5,8 +5,8 @@ use std::ops::{AddAssign, Sub}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, ensure_ne, to_binary, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg, - Empty, Env, MessageInfo, Order, Response, StakingMsg, StdResult, + ensure, ensure_ne, to_json_binary, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, + DistributionMsg, Empty, Env, MessageInfo, Order, Response, StakingMsg, StdResult, }; use cw1::CanExecuteResponse; use cw1_whitelist::{ @@ -304,17 +304,17 @@ where #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::AdminList {} => to_binary(&query_admin_list(deps)?), - QueryMsg::Allowance { spender } => to_binary(&query_allowance(deps, env, spender)?), - QueryMsg::Permissions { spender } => to_binary(&query_permissions(deps, spender)?), + QueryMsg::AdminList {} => to_json_binary(&query_admin_list(deps)?), + QueryMsg::Allowance { spender } => to_json_binary(&query_allowance(deps, env, spender)?), + QueryMsg::Permissions { spender } => to_json_binary(&query_permissions(deps, spender)?), QueryMsg::CanExecute { sender, msg } => { - to_binary(&query_can_execute(deps, env, sender, msg)?) + to_json_binary(&query_can_execute(deps, env, sender, msg)?) } QueryMsg::AllAllowances { start_after, limit } => { - to_binary(&query_all_allowances(deps, env, start_after, limit)?) + to_json_binary(&query_all_allowances(deps, env, start_after, limit)?) } QueryMsg::AllPermissions { start_after, limit } => { - to_binary(&query_all_permissions(deps, start_after, limit)?) + to_json_binary(&query_all_permissions(deps, start_after, limit)?) } } } @@ -453,7 +453,7 @@ pub fn query_all_permissions( } // Migrate contract if version is lower than current version -#[entry_point] +#[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result { let version: Version = CONTRACT_VERSION.parse()?; let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?; diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index b13fea207..77b085579 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -4,7 +4,7 @@ use std::fmt; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Addr, Api, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, + to_json_binary, Addr, Api, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult, }; @@ -118,8 +118,10 @@ fn can_execute(deps: Deps, sender: &str) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::AdminList {} => to_binary(&query_admin_list(deps)?), - QueryMsg::CanExecute { sender, msg } => to_binary(&query_can_execute(deps, sender, msg)?), + QueryMsg::AdminList {} => to_json_binary(&query_admin_list(deps)?), + QueryMsg::CanExecute { sender, msg } => { + to_json_binary(&query_can_execute(deps, sender, msg)?) + } } } @@ -242,7 +244,7 @@ mod tests { .into(), WasmMsg::Execute { contract_addr: "some contract".into(), - msg: to_binary(&freeze).unwrap(), + msg: to_json_binary(&freeze).unwrap(), funds: vec![], } .into(), diff --git a/contracts/cw1-whitelist/src/integration_tests.rs b/contracts/cw1-whitelist/src/integration_tests.rs index eeb3b5a3b..73dc1f7f0 100644 --- a/contracts/cw1-whitelist/src/integration_tests.rs +++ b/contracts/cw1-whitelist/src/integration_tests.rs @@ -1,7 +1,9 @@ use crate::msg::{AdminListResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; use anyhow::{anyhow, Result}; use assert_matches::assert_matches; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, Empty, QueryRequest, StdError, WasmMsg, WasmQuery}; +use cosmwasm_std::{ + to_json_binary, Addr, CosmosMsg, Empty, QueryRequest, StdError, WasmMsg, WasmQuery, +}; use cw1::Cw1Contract; use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; use derivative::Derivative; @@ -68,7 +70,7 @@ impl Suite { let execute: ExecuteMsg = ExecuteMsg::Execute { msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: target_contract.to_string(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], })], }; @@ -88,7 +90,7 @@ impl Suite { { self.app.wrap().query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: target_contract.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) } } diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index 38b36da46..a9a4a0907 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -697,7 +697,7 @@ mod tests { amount: transfer, msg: send_msg.clone(), } - .into_binary() + .into_json_binary() .unwrap(); assert_eq!( res.messages[0], diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 6f92ac227..4fd8a99e0 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::Order::Ascending; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; use cw2::{ensure_from_older_version, set_contract_version}; @@ -506,32 +506,32 @@ pub fn execute_upload_logo( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?), - QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?), - QueryMsg::Minter {} => to_binary(&query_minter(deps)?), + QueryMsg::Balance { address } => to_json_binary(&query_balance(deps, address)?), + QueryMsg::TokenInfo {} => to_json_binary(&query_token_info(deps)?), + QueryMsg::Minter {} => to_json_binary(&query_minter(deps)?), QueryMsg::Allowance { owner, spender } => { - to_binary(&query_allowance(deps, owner, spender)?) + to_json_binary(&query_allowance(deps, owner, spender)?) } QueryMsg::AllAllowances { owner, start_after, limit, - } => to_binary(&query_owner_allowances(deps, owner, start_after, limit)?), + } => to_json_binary(&query_owner_allowances(deps, owner, start_after, limit)?), QueryMsg::AllSpenderAllowances { spender, start_after, limit, - } => to_binary(&query_spender_allowances( + } => to_json_binary(&query_spender_allowances( deps, spender, start_after, limit, )?), QueryMsg::AllAccounts { start_after, limit } => { - to_binary(&query_all_accounts(deps, start_after, limit)?) + to_json_binary(&query_all_accounts(deps, start_after, limit)?) } - QueryMsg::MarketingInfo {} => to_binary(&query_marketing_info(deps)?), - QueryMsg::DownloadLogo {} => to_binary(&query_download_logo(deps)?), + QueryMsg::MarketingInfo {} => to_json_binary(&query_marketing_info(deps)?), + QueryMsg::DownloadLogo {} => to_json_binary(&query_download_logo(deps)?), } } @@ -607,7 +607,7 @@ mod tests { use cosmwasm_std::testing::{ mock_dependencies, mock_dependencies_with_balance, mock_env, mock_info, }; - use cosmwasm_std::{coins, from_binary, Addr, CosmosMsg, StdError, SubMsg, WasmMsg}; + use cosmwasm_std::{coins, from_json, Addr, CosmosMsg, StdError, SubMsg, WasmMsg}; use super::*; use crate::msg::InstantiateMarketingInfo; @@ -957,7 +957,7 @@ mod tests { assert!(res.is_ok()); let query_minter_msg = QueryMsg::Minter {}; let res = query(deps.as_ref(), env, query_minter_msg); - let mint: MinterResponse = from_binary(&res.unwrap()).unwrap(); + let mint: MinterResponse = from_json(res.unwrap()).unwrap(); // Minter cannot update cap. assert!(mint.cap == cap); @@ -1007,7 +1007,7 @@ mod tests { assert!(res.is_ok()); let query_minter_msg = QueryMsg::Minter {}; let res = query(deps.as_ref(), env, query_minter_msg); - let mint: Option = from_binary(&res.unwrap()).unwrap(); + let mint: Option = from_json(res.unwrap()).unwrap(); // Check that mint information was removed. assert_eq!(mint, None); @@ -1124,7 +1124,7 @@ mod tests { QueryMsg::Balance { address: addr1 }, ) .unwrap(); - let loaded: BalanceResponse = from_binary(&data).unwrap(); + let loaded: BalanceResponse = from_json(data).unwrap(); assert_eq!(loaded.balance, amount1); // check balance query (empty) @@ -1136,7 +1136,7 @@ mod tests { }, ) .unwrap(); - let loaded: BalanceResponse = from_binary(&data).unwrap(); + let loaded: BalanceResponse = from_json(data).unwrap(); assert_eq!(loaded.balance, Uint128::zero()); } @@ -1298,7 +1298,7 @@ mod tests { amount: transfer, msg: send_msg, } - .into_binary() + .into_json_binary() .unwrap(); // and this is how it must be wrapped for the vm to process it assert_eq!( @@ -1383,7 +1383,7 @@ mod tests { let expires = Expiration::AtHeight(123_456); let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cw20_addr.to_string(), - msg: to_binary(&ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&ExecuteMsg::IncreaseAllowance { spender: "spender".into(), amount: allow1, expires: Some(expires), @@ -1399,7 +1399,7 @@ mod tests { CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: cw20_addr.to_string(), new_code_id: cw20_id, - msg: to_binary(&MigrateMsg {}).unwrap(), + msg: to_json_binary(&MigrateMsg {}).unwrap(), }), ) .unwrap(); diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index f465134d2..68b8fefdc 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -83,7 +83,7 @@ mod tests { use super::*; use cosmwasm_std::testing::{mock_dependencies_with_balance, mock_env, mock_info}; - use cosmwasm_std::{coins, from_binary, DepsMut, Uint128}; + use cosmwasm_std::{coins, from_json, DepsMut, Uint128}; use cw20::{Cw20Coin, Expiration, TokenInfoResponse}; use crate::contract::{execute, instantiate, query, query_token_info}; @@ -220,7 +220,7 @@ mod tests { limit: None, }; let allowances: AllSpenderAllowancesResponse = - from_binary(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 2); // one is owner1 (order of CanonicalAddr uncorrelated with String) @@ -230,7 +230,7 @@ mod tests { limit: Some(1), }; let allowances: AllSpenderAllowancesResponse = - from_binary(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; assert_eq!(&allow.owner, &owner1); @@ -244,7 +244,7 @@ mod tests { limit: Some(10000), }; let allowances: AllSpenderAllowancesResponse = - from_binary(&query(deps.as_ref(), env, msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env, msg).unwrap()).unwrap(); assert_eq!(allowances.allowances.len(), 1); let allow = &allowances.allowances[0]; assert_eq!(&allow.owner, &owner2); diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index f33aad865..8aa04c290 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, Order, - PortIdResponse, Response, StdError, StdResult, + from_json, to_json_binary, Addr, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, + Order, PortIdResponse, Response, StdError, StdResult, }; use semver::Version; @@ -85,7 +85,7 @@ pub fn execute_receive( ) -> Result { nonpayable(&info)?; - let msg: TransferMsg = from_binary(&wrapper.msg)?; + let msg: TransferMsg = from_json(&wrapper.msg)?; let amount = Amount::Cw20(Cw20Coin { address: info.sender.to_string(), amount: wrapper.amount, @@ -147,7 +147,7 @@ pub fn execute_transfer( // prepare ibc message let msg = IbcMsg::SendPacket { channel_id: msg.channel, - data: to_binary(&packet)?, + data: to_json_binary(&packet)?, timeout: timeout.into(), }; @@ -274,21 +274,21 @@ fn from_semver(err: semver::Error) -> StdError { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Port {} => to_binary(&query_port(deps)?), - QueryMsg::ListChannels {} => to_binary(&query_list(deps)?), - QueryMsg::Channel { id } => to_binary(&query_channel(deps, id)?), - QueryMsg::Config {} => to_binary(&query_config(deps)?), - QueryMsg::Allowed { contract } => to_binary(&query_allowed(deps, contract)?), + QueryMsg::Port {} => to_json_binary(&query_port(deps)?), + QueryMsg::ListChannels {} => to_json_binary(&query_list(deps)?), + QueryMsg::Channel { id } => to_json_binary(&query_channel(deps, id)?), + QueryMsg::Config {} => to_json_binary(&query_config(deps)?), + QueryMsg::Allowed { contract } => to_json_binary(&query_allowed(deps, contract)?), QueryMsg::ListAllowed { start_after, limit } => { - to_binary(&list_allowed(deps, start_after, limit)?) + to_json_binary(&list_allowed(deps, start_after, limit)?) } - QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), + QueryMsg::Admin {} => to_json_binary(&ADMIN.query_admin(deps)?), } } fn query_port(deps: Deps) -> StdResult { let query = IbcQuery::PortId {}.into(); - let PortIdResponse { port_id } = deps.querier.query(&query)?; + let PortIdResponse { port_id, .. } = deps.querier.query(&query)?; Ok(PortResponse { port_id }) } @@ -395,7 +395,7 @@ mod test { let deps = setup(&["channel-3", "channel-7"], &[]); let raw_list = query(deps.as_ref(), mock_env(), QueryMsg::ListChannels {}).unwrap(); - let list_res: ListChannelsResponse = from_binary(&raw_list).unwrap(); + let list_res: ListChannelsResponse = from_json(raw_list).unwrap(); assert_eq!(2, list_res.channels.len()); assert_eq!(mock_channel_info("channel-3"), list_res.channels[0]); assert_eq!(mock_channel_info("channel-7"), list_res.channels[1]); @@ -408,7 +408,7 @@ mod test { }, ) .unwrap(); - let chan_res: ChannelResponse = from_binary(&raw_channel).unwrap(); + let chan_res: ChannelResponse = from_json(raw_channel).unwrap(); assert_eq!(chan_res.info, mock_channel_info("channel-3")); assert_eq!(0, chan_res.total_sent.len()); assert_eq!(0, chan_res.balances.len()); @@ -421,24 +421,27 @@ mod test { }, ) .unwrap_err(); - assert_eq!(err, StdError::not_found("cw20_ics20::state::ChannelInfo")); + assert_eq!(err, StdError::not_found("type: cw20_ics20::state::ChannelInfo; key: [00, 0C, 63, 68, 61, 6E, 6E, 65, 6C, 5F, 69, 6E, 66, 6F, 63, 68, 61, 6E, 6E, 65, 6C, 2D, 31, 30]")); } #[test] fn proper_checks_on_execute_native() { + let foobar = "foobar"; + let foreign = "foreign-address"; + let send_channel = "channel-5"; let mut deps = setup(&[send_channel, "channel-10"], &[]); let mut transfer = TransferMsg { channel: send_channel.to_string(), - remote_address: "foreign-address".to_string(), + remote_address: foreign.to_string(), timeout: None, memo: None, }; // works with proper funds let msg = ExecuteMsg::Transfer(transfer.clone()); - let info = mock_info("foobar", &coins(1234567, "ucosm")); + let info = mock_info(foobar, &coins(1234567, "ucosm")); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(res.messages[0].gas_limit, None); assert_eq!(1, res.messages.len()); @@ -451,31 +454,31 @@ mod test { let expected_timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); assert_eq!(timeout, &expected_timeout.into()); assert_eq!(channel_id.as_str(), send_channel); - let msg: Ics20Packet = from_binary(data).unwrap(); + let msg: Ics20Packet = from_json(data).unwrap(); assert_eq!(msg.amount, Uint128::new(1234567)); assert_eq!(msg.denom.as_str(), "ucosm"); - assert_eq!(msg.sender.as_str(), "foobar"); - assert_eq!(msg.receiver.as_str(), "foreign-address"); + assert_eq!(msg.sender.as_str(), foobar); + assert_eq!(msg.receiver.as_str(), foreign); } else { panic!("Unexpected return message: {:?}", res.messages[0]); } // reject with no funds let msg = ExecuteMsg::Transfer(transfer.clone()); - let info = mock_info("foobar", &[]); + let info = mock_info(foobar, &[]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Payment(PaymentError::NoFunds {})); // reject with multiple tokens funds let msg = ExecuteMsg::Transfer(transfer.clone()); - let info = mock_info("foobar", &[coin(1234567, "ucosm"), coin(54321, "uatom")]); + let info = mock_info(foobar, &[coin(1234567, "ucosm"), coin(54321, "uatom")]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Payment(PaymentError::MultipleDenoms {})); // reject with bad channel id transfer.channel = "channel-45".to_string(); let msg = ExecuteMsg::Transfer(transfer); - let info = mock_info("foobar", &coins(1234567, "ucosm")); + let info = mock_info(foobar, &coins(1234567, "ucosm")); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!( err, @@ -489,18 +492,20 @@ mod test { fn proper_checks_on_execute_cw20() { let send_channel = "channel-15"; let cw20_addr = "my-token"; + let foreign = "foreign-address"; + let sender = "my-account"; let mut deps = setup(&["channel-3", send_channel], &[(cw20_addr, 123456)]); let transfer = TransferMsg { channel: send_channel.to_string(), - remote_address: "foreign-address".to_string(), + remote_address: foreign.to_string(), timeout: Some(7777), memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: "my-account".into(), + sender: sender.into(), amount: Uint128::new(888777666), - msg: to_binary(&transfer).unwrap(), + msg: to_json_binary(&transfer).unwrap(), }); // works with proper funds @@ -517,11 +522,11 @@ mod test { let expected_timeout = mock_env().block.time.plus_seconds(7777); assert_eq!(timeout, &expected_timeout.into()); assert_eq!(channel_id.as_str(), send_channel); - let msg: Ics20Packet = from_binary(data).unwrap(); + let msg: Ics20Packet = from_json(data).unwrap(); assert_eq!(msg.amount, Uint128::new(888777666)); assert_eq!(msg.denom, format!("cw20:{cw20_addr}")); - assert_eq!(msg.sender.as_str(), "my-account"); - assert_eq!(msg.receiver.as_str(), "foreign-address"); + assert_eq!(msg.sender.as_str(), sender); + assert_eq!(msg.receiver.as_str(), foreign); } else { panic!("Unexpected return message: {:?}", res.messages[0]); } @@ -547,7 +552,7 @@ mod test { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "my-account".into(), amount: Uint128::new(888777666), - msg: to_binary(&transfer).unwrap(), + msg: to_json_binary(&transfer).unwrap(), }); // rejected as not on allow list @@ -618,6 +623,9 @@ mod test { let send_channel = "channel-5"; let mut deps = setup(&[send_channel, "channel-10"], &[]); + let foobar = "foobar"; + let foreign = "foreign-address"; + let transfer = TransferMsg { channel: send_channel.to_string(), remote_address: "foreign-address".to_string(), @@ -627,7 +635,7 @@ mod test { // works with proper funds let msg = ExecuteMsg::Transfer(transfer); - let info = mock_info("foobar", &coins(1234567, "ucosm")); + let info = mock_info(foobar, &coins(1234567, "ucosm")); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(res.messages[0].gas_limit, None); assert_eq!(1, res.messages.len()); @@ -640,11 +648,11 @@ mod test { let expected_timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); assert_eq!(timeout, &expected_timeout.into()); assert_eq!(channel_id.as_str(), send_channel); - let msg: Ics20Packet = from_binary(data).unwrap(); + let msg: Ics20Packet = from_json(data).unwrap(); assert_eq!(msg.amount, Uint128::new(1234567)); assert_eq!(msg.denom.as_str(), "ucosm"); - assert_eq!(msg.sender.as_str(), "foobar"); - assert_eq!(msg.receiver.as_str(), "foreign-address"); + assert_eq!(msg.sender.as_str(), foobar); + assert_eq!(msg.receiver.as_str(), foreign); assert_eq!( msg.memo .expect("Memo was None when Some was expected") @@ -669,8 +677,9 @@ mod test { #[test] fn memo_is_backwards_compatible() { let mut deps = setup(&["channel-5", "channel-10"], &[]); - let transfer: TransferMsg = cosmwasm_std::from_slice( - br#"{"channel": "channel-5", "remote_address": "foreign-address"}"#, + + let transfer: TransferMsg = cosmwasm_std::from_json( + r#"{"channel": "channel-5", "remote_address": "foreign-address"}"#, ) .unwrap(); @@ -684,7 +693,7 @@ mod test { timeout: _, }) = &res.messages[0].msg { - let msg: Ics20Packet = from_binary(data).unwrap(); + let msg: Ics20Packet = from_json(data).unwrap(); assert_eq!(msg.memo, None); // This is the old version of the Ics20Packet. Deserializing into it @@ -697,7 +706,7 @@ mod test { pub receiver: String, } - let _msg: Ics20PacketNoMemo = from_binary(data).unwrap(); + let _msg: Ics20PacketNoMemo = from_json(data).unwrap(); } else { panic!("Unexpected return message: {:?}", res.messages[0]); } diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index ff62c90ce..fdc87726b 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -2,8 +2,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, entry_point, from_binary, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, + attr, from_json, to_json_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, SubMsg, SubMsgResult, Uint128, WasmMsg, @@ -74,13 +76,13 @@ pub enum Ics20Ack { // create a serialized success message fn ack_success() -> Binary { let res = Ics20Ack::Result(b"1".into()); - to_binary(&res).unwrap() + to_json_binary(&res).unwrap() } // create a serialized error message fn ack_fail(err: String) -> Binary { let res = Ics20Ack::Error(err); - to_binary(&res).unwrap() + to_json_binary(&res).unwrap() } const RECEIVE_ID: u64 = 1337; @@ -239,7 +241,7 @@ fn do_ibc_packet_receive( deps: DepsMut, packet: &IbcPacket, ) -> Result { - let msg: Ics20Packet = from_binary(&packet.data)?; + let msg: Ics20Packet = from_json(&packet.data)?; let channel = packet.dest.channel_id.clone(); // If the token originated on the remote chain, it looks like "ucosm". @@ -304,7 +306,7 @@ pub fn ibc_packet_ack( // Design decision: should we trap error like in receive? // TODO: unsure... as it is now a failed ack handling would revert the tx and would be // retried again and again. is that good? - let ics20msg: Ics20Ack = from_binary(&msg.acknowledgement.data)?; + let ics20msg: Ics20Ack = from_json(&msg.acknowledgement.data)?; match ics20msg { Ics20Ack::Result(_) => on_packet_success(deps, msg.original_packet), Ics20Ack::Error(err) => on_packet_failure(deps, msg.original_packet, err), @@ -325,7 +327,7 @@ pub fn ibc_packet_timeout( // update the balance stored on this (channel, denom) index fn on_packet_success(_deps: DepsMut, packet: IbcPacket) -> Result { - let msg: Ics20Packet = from_binary(&packet.data)?; + let msg: Ics20Packet = from_json(packet.data)?; // similar event messages like ibctransfer module let attributes = vec![ @@ -346,7 +348,7 @@ fn on_packet_failure( packet: IbcPacket, err: String, ) -> Result { - let msg: Ics20Packet = from_binary(&packet.data)?; + let msg: Ics20Packet = from_json(&packet.data)?; // undo the balance update on failure (as we pre-emptively added it on send) reduce_channel_balance(deps.storage, &packet.src.channel_id, &msg.denom, msg.amount)?; @@ -385,7 +387,7 @@ fn send_amount(amount: Amount, recipient: String) -> CosmosMsg { }; WasmMsg::Execute { contract_addr: coin.address, - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), funds: vec![], } .into() @@ -401,7 +403,7 @@ mod test { use crate::contract::{execute, migrate, query_channel}; use crate::msg::{ExecuteMsg, MigrateMsg, TransferMsg}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{coins, to_vec, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; + use cosmwasm_std::{coins, to_json_vec, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; use cw20::Cw20ReceiveMsg; #[test] @@ -409,10 +411,10 @@ mod test { let success = Ics20Ack::Result(b"1".into()); let fail = Ics20Ack::Error("bad coin".into()); - let success_json = String::from_utf8(to_vec(&success).unwrap()).unwrap(); + let success_json = String::from_utf8(to_json_vec(&success).unwrap()).unwrap(); assert_eq!(r#"{"result":"MQ=="}"#, success_json.as_str()); - let fail_json = String::from_utf8(to_vec(&fail).unwrap()).unwrap(); + let fail_json = String::from_utf8(to_json_vec(&fail).unwrap()).unwrap(); assert_eq!(r#"{"error":"bad coin"}"#, fail_json.as_str()); } @@ -427,7 +429,7 @@ mod test { // Example message generated from the SDK let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n"}"#; - let encdoded = String::from_utf8(to_vec(&packet).unwrap()).unwrap(); + let encdoded = String::from_utf8(to_json_vec(&packet).unwrap()).unwrap(); assert_eq!(expected, encdoded.as_str()); } @@ -443,7 +445,7 @@ mod test { }; let exec = WasmMsg::Execute { contract_addr: address.into(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), funds: vec![], }; let mut msg = SubMsg::reply_on_error(exec, RECEIVE_ID); @@ -477,7 +479,7 @@ mod test { }; print!("Packet denom: {}", &data.denom); IbcPacket::new( - to_binary(&data).unwrap(), + to_json_binary(&data).unwrap(), IbcEndpoint { port_id: REMOTE_PORT.to_string(), channel_id: "channel-1234".to_string(), @@ -496,6 +498,9 @@ mod test { let send_channel = "channel-9"; let cw20_addr = "token-addr"; let cw20_denom = "cw20:token-addr"; + let local_rcpt = "local-rcpt"; + let local_sender = "local-sender"; + let remote_rcpt = "remote-rcpt"; let gas_limit = 1234567; let mut deps = setup( &["channel-1", "channel-7", send_channel], @@ -503,29 +508,29 @@ mod test { ); // prepare some mock packets - let recv_packet = mock_receive_packet(send_channel, 876543210, cw20_denom, "local-rcpt"); + let recv_packet = mock_receive_packet(send_channel, 876543210, cw20_denom, local_rcpt); let recv_high_packet = - mock_receive_packet(send_channel, 1876543210, cw20_denom, "local-rcpt"); + mock_receive_packet(send_channel, 1876543210, cw20_denom, local_rcpt); // cannot receive this denom yet let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); // we send some cw20 tokens over let transfer = TransferMsg { channel: send_channel.to_string(), - remote_address: "remote-rcpt".to_string(), + remote_address: remote_rcpt.to_string(), timeout: None, memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: "local-sender".to_string(), + sender: local_sender.to_string(), amount: Uint128::new(987654321), - msg: to_binary(&transfer).unwrap(), + msg: to_json_binary(&transfer).unwrap(), }); let info = mock_info(cw20_addr, &[]); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -533,16 +538,17 @@ mod test { let expected = Ics20Packet { denom: cw20_denom.into(), amount: Uint128::new(987654321), - sender: "local-sender".to_string(), - receiver: "remote-rcpt".to_string(), + sender: local_sender.to_string(), + receiver: remote_rcpt.to_string(), memo: None, }; let timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); + assert_eq!( &res.messages[0], &SubMsg::new(IbcMsg::SendPacket { channel_id: send_channel.to_string(), - data: to_binary(&expected).unwrap(), + data: to_json_binary(&expected).unwrap(), timeout: IbcTimeout::with_timestamp(timeout), }) ); @@ -556,7 +562,7 @@ mod test { let msg = IbcPacketReceiveMsg::new(recv_high_packet); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); assert_eq!(ack, no_funds); // we can receive less than we sent @@ -564,10 +570,10 @@ mod test { let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert_eq!(1, res.messages.len()); assert_eq!( - cw20_payment(876543210, cw20_addr, "local-rcpt", Some(gas_limit)), + cw20_payment(876543210, cw20_addr, local_rcpt, Some(gas_limit)), res.messages[0] ); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); assert!(matches!(ack, Ics20Ack::Result(_))); // TODO: we need to call the reply block @@ -593,7 +599,7 @@ mod test { let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); @@ -616,7 +622,7 @@ mod test { let msg = IbcPacketReceiveMsg::new(recv_high_packet); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); assert_eq!(ack, no_funds); // we can receive less than we sent @@ -627,7 +633,7 @@ mod test { native_payment(876543210, denom, "local-rcpt"), res.messages[0] ); - let ack: Ics20Ack = from_binary(&res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); assert!(matches!(ack, Ics20Ack::Result(_))); // only need to call reply block on error case diff --git a/contracts/cw20-ics20/src/migrations.rs b/contracts/cw20-ics20/src/migrations.rs index 3ff2fe09f..39fb9d4b5 100644 --- a/contracts/cw20-ics20/src/migrations.rs +++ b/contracts/cw20-ics20/src/migrations.rs @@ -19,7 +19,7 @@ pub mod v2 { use crate::amount::Amount; use crate::state::{ChannelState, CHANNEL_INFO, CHANNEL_STATE}; use crate::ContractError; - use cosmwasm_std::{to_binary, Addr, DepsMut, Env, Order, StdResult, WasmQuery}; + use cosmwasm_std::{to_json_binary, Addr, DepsMut, Env, Order, StdResult, WasmQuery}; use cw20::{BalanceResponse, Cw20QueryMsg}; pub fn update_balances(mut deps: DepsMut, env: &Env) -> Result<(), ContractError> { @@ -62,7 +62,7 @@ pub mod v2 { // `Cw20Contract(contract.clone()).balance(&deps.querier, contract)?` let query = WasmQuery::Smart { contract_addr: coin.address, - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: contract.into(), })?, }; diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 27e2b4f0b..105079314 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -75,7 +75,7 @@ pub fn setup( gov_contract: "gov".to_string(), allowlist, }; - let info = mock_info(&String::from("anyone"), &[]); + let info = mock_info("anyone", &[]); let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); assert_eq!(0, res.messages.len()); diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index a56d65d1a..dd1d56e4a 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, + to_json_binary, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdResult, }; @@ -240,24 +240,28 @@ pub fn execute_close( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Threshold {} => to_binary(&query_threshold(deps)?), - QueryMsg::Proposal { proposal_id } => to_binary(&query_proposal(deps, env, proposal_id)?), - QueryMsg::Vote { proposal_id, voter } => to_binary(&query_vote(deps, proposal_id, voter)?), + QueryMsg::Threshold {} => to_json_binary(&query_threshold(deps)?), + QueryMsg::Proposal { proposal_id } => { + to_json_binary(&query_proposal(deps, env, proposal_id)?) + } + QueryMsg::Vote { proposal_id, voter } => { + to_json_binary(&query_vote(deps, proposal_id, voter)?) + } QueryMsg::ListProposals { start_after, limit } => { - to_binary(&list_proposals(deps, env, start_after, limit)?) + to_json_binary(&list_proposals(deps, env, start_after, limit)?) } QueryMsg::ReverseProposals { start_before, limit, - } => to_binary(&reverse_proposals(deps, env, start_before, limit)?), + } => to_json_binary(&reverse_proposals(deps, env, start_before, limit)?), QueryMsg::ListVotes { proposal_id, start_after, limit, - } => to_binary(&list_votes(deps, proposal_id, start_after, limit)?), - QueryMsg::Voter { address } => to_binary(&query_voter(deps, address)?), + } => to_json_binary(&list_votes(deps, proposal_id, start_after, limit)?), + QueryMsg::Voter { address } => to_json_binary(&query_voter(deps, address)?), QueryMsg::ListVoters { start_after, limit } => { - to_binary(&list_voters(deps, start_after, limit)?) + to_json_binary(&list_voters(deps, start_after, limit)?) } } } @@ -412,7 +416,7 @@ fn list_voters( #[cfg(test)] mod tests { use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coin, from_binary, BankMsg, Decimal}; + use cosmwasm_std::{coin, from_json, BankMsg, Decimal}; use cw2::{get_contract_version, ContractVersion}; use cw_utils::{Duration, Threshold}; @@ -485,8 +489,7 @@ mod tests { start_after: None, limit: None, }; - let votes: VoteListResponse = - from_binary(&query(deps, mock_env(), voters).unwrap()).unwrap(); + let votes: VoteListResponse = from_json(&query(deps, mock_env(), voters).unwrap()).unwrap(); // Sum the weights of the Yes votes to get the tally votes .votes @@ -1017,7 +1020,7 @@ mod tests { }; // Proposal should now be passed - let prop: ProposalResponse = from_binary( + let prop: ProposalResponse = from_json( &query( deps.as_ref(), env.clone(), diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index d9caf9e41..f8c344f7c 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use cosmwasm_std::{to_binary, Addr, Empty, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, Empty, Uint128, WasmMsg}; use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; @@ -104,7 +104,7 @@ fn cw3_controls_cw20() { let execute_mint_msg = WasmMsg::Execute { contract_addr: cw20_addr.to_string(), - msg: to_binary(&cw20_mint_msg).unwrap(), + msg: to_json_binary(&cw20_mint_msg).unwrap(), funds: vec![], }; let propose_msg = ExecuteMsg::Propose { diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 51ad82a3a..e0e731c2e 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, + to_json_binary, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdResult, }; @@ -307,26 +307,30 @@ pub fn execute_membership_hook( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Threshold {} => to_binary(&query_threshold(deps)?), - QueryMsg::Proposal { proposal_id } => to_binary(&query_proposal(deps, env, proposal_id)?), - QueryMsg::Vote { proposal_id, voter } => to_binary(&query_vote(deps, proposal_id, voter)?), + QueryMsg::Threshold {} => to_json_binary(&query_threshold(deps)?), + QueryMsg::Proposal { proposal_id } => { + to_json_binary(&query_proposal(deps, env, proposal_id)?) + } + QueryMsg::Vote { proposal_id, voter } => { + to_json_binary(&query_vote(deps, proposal_id, voter)?) + } QueryMsg::ListProposals { start_after, limit } => { - to_binary(&list_proposals(deps, env, start_after, limit)?) + to_json_binary(&list_proposals(deps, env, start_after, limit)?) } QueryMsg::ReverseProposals { start_before, limit, - } => to_binary(&reverse_proposals(deps, env, start_before, limit)?), + } => to_json_binary(&reverse_proposals(deps, env, start_before, limit)?), QueryMsg::ListVotes { proposal_id, start_after, limit, - } => to_binary(&list_votes(deps, proposal_id, start_after, limit)?), - QueryMsg::Voter { address } => to_binary(&query_voter(deps, address)?), + } => to_json_binary(&list_votes(deps, proposal_id, start_after, limit)?), + QueryMsg::Voter { address } => to_json_binary(&query_voter(deps, address)?), QueryMsg::ListVoters { start_after, limit } => { - to_binary(&list_voters(deps, start_after, limit)?) + to_json_binary(&list_voters(deps, start_after, limit)?) } - QueryMsg::Config {} => to_binary(&query_config(deps)?), + QueryMsg::Config {} => to_json_binary(&query_config(deps)?), } } diff --git a/contracts/cw4-group/src/contract.rs b/contracts/cw4-group/src/contract.rs index 68bd654ae..5956f47c3 100644 --- a/contracts/cw4-group/src/contract.rs +++ b/contracts/cw4-group/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, - SubMsg, Uint64, + attr, to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, + StdResult, SubMsg, Uint64, }; use cw2::set_contract_version; use cw4::{ @@ -163,15 +163,15 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Member { addr, at_height: height, - } => to_binary(&query_member(deps, addr, height)?), + } => to_json_binary(&query_member(deps, addr, height)?), QueryMsg::ListMembers { start_after, limit } => { - to_binary(&query_list_members(deps, start_after, limit)?) + to_json_binary(&query_list_members(deps, start_after, limit)?) } QueryMsg::TotalWeight { at_height: height } => { - to_binary(&query_total_weight(deps, height)?) + to_json_binary(&query_total_weight(deps, height)?) } - QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), - QueryMsg::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?), + QueryMsg::Admin {} => to_json_binary(&ADMIN.query_admin(deps)?), + QueryMsg::Hooks {} => to_json_binary(&HOOKS.query_hooks(deps)?), } } diff --git a/contracts/cw4-group/src/helpers.rs b/contracts/cw4-group/src/helpers.rs index 9611ed9d6..887d0d9c1 100644 --- a/contracts/cw4-group/src/helpers.rs +++ b/contracts/cw4-group/src/helpers.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use cw4::{Cw4Contract, Member}; use crate::{msg::ExecuteMsg, ContractError}; @@ -29,7 +29,7 @@ impl Cw4GroupContract { fn encode_msg(&self, msg: ExecuteMsg) -> StdResult { Ok(WasmMsg::Execute { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], } .into()) diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index 39bd87978..202354a39 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -1,5 +1,5 @@ use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{from_slice, Addr, Api, DepsMut, OwnedDeps, Querier, Storage, SubMsg}; +use cosmwasm_std::{from_json, Addr, Api, DepsMut, OwnedDeps, Querier, Storage, SubMsg}; use cw4::{member_key, Member, MemberChangedHookMsg, MemberDiff, TOTAL_KEY}; use cw_controllers::{AdminError, HookError}; @@ -278,8 +278,8 @@ fn add_remove_hooks() { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); + let contract1 = "hook1".to_string(); + let contract2 = "hook2".to_string(); let add_msg = ExecuteMsg::AddHook { addr: contract1.clone(), @@ -346,8 +346,8 @@ fn hooks_fire() { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); + let contract1 = "hook1".to_string(); + let contract2 = "hook2".to_string(); // register 2 hooks let admin_info = mock_info(INIT_ADMIN, &[]); @@ -407,12 +407,12 @@ fn raw_queries_work() { // get total from raw key let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); - let total: u64 = from_slice(&total_raw).unwrap(); + let total: u64 = from_json(total_raw).unwrap(); assert_eq!(17, total); // get member votes from raw key let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); - let member2: u64 = from_slice(&member2_raw).unwrap(); + let member2: u64 = from_json(member2_raw).unwrap(); assert_eq!(6, member2); // and execute misses diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 9aa97ea30..4b12df0ea 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - coins, from_slice, to_binary, Addr, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Order, - Response, StdResult, Storage, SubMsg, Uint128, WasmMsg, + coins, from_json, to_json_binary, Addr, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, + Order, Response, StdResult, Storage, SubMsg, Uint128, WasmMsg, }; use cw2::set_contract_version; @@ -131,7 +131,7 @@ pub fn execute_receive( // wrapper.sender is the address of the user that requested the cw20 contract to send this. // This cannot be fully trusted (the cw20 contract can fake it), so only use it for actions // in the address's favor (like paying/bonding tokens, not withdrawls) - let msg: ReceiveMsg = from_slice(&wrapper.msg)?; + let msg: ReceiveMsg = from_json(&wrapper.msg)?; let balance = Balance::Cw20(Cw20CoinVerified { address: info.sender, amount: wrapper.amount, @@ -268,7 +268,7 @@ pub fn execute_claim( }; let message = SubMsg::new(WasmMsg::Execute { contract_addr: addr.into(), - msg: to_binary(&transfer)?, + msg: to_json_binary(&transfer)?, funds: vec![], }); (amount_str, message) @@ -293,17 +293,17 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Member { addr, at_height: height, - } => to_binary(&query_member(deps, addr, height)?), + } => to_json_binary(&query_member(deps, addr, height)?), QueryMsg::ListMembers { start_after, limit } => { - to_binary(&list_members(deps, start_after, limit)?) + to_json_binary(&list_members(deps, start_after, limit)?) } - QueryMsg::TotalWeight {} => to_binary(&query_total_weight(deps)?), + QueryMsg::TotalWeight {} => to_json_binary(&query_total_weight(deps)?), QueryMsg::Claims { address } => { - to_binary(&CLAIMS.query_claims(deps, &deps.api.addr_validate(&address)?)?) + to_json_binary(&CLAIMS.query_claims(deps, &deps.api.addr_validate(&address)?)?) } - QueryMsg::Staked { address } => to_binary(&query_staked(deps, address)?), - QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), - QueryMsg::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?), + QueryMsg::Staked { address } => to_json_binary(&query_staked(deps, address)?), + QueryMsg::Admin {} => to_json_binary(&ADMIN.query_admin(deps)?), + QueryMsg::Hooks {} => to_json_binary(&HOOKS.query_hooks(deps)?), } } @@ -359,7 +359,7 @@ fn list_members( mod tests { use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{ - coin, from_slice, CosmosMsg, OverflowError, OverflowOperation, StdError, Storage, + coin, from_json, CosmosMsg, OverflowError, OverflowOperation, StdError, Storage, }; use cw20::Denom; use cw4::{member_key, TOTAL_KEY}; @@ -440,7 +440,7 @@ mod tests { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: addr.to_string(), amount: Uint128::new(*stake), - msg: to_binary(&ReceiveMsg::Bond {}).unwrap(), + msg: to_json_binary(&ReceiveMsg::Bond {}).unwrap(), }); let info = mock_info(CW20_ADDRESS, &[]); execute(deps.branch(), env.clone(), info, msg).unwrap(); @@ -478,7 +478,7 @@ mod tests { fn get_member(deps: Deps, addr: String, at_height: Option) -> Option { let raw = query(deps, mock_env(), QueryMsg::Member { addr, at_height }).unwrap(); - let res: MemberResponse = from_slice(&raw).unwrap(); + let res: MemberResponse = from_json(raw).unwrap(); res.weight } @@ -512,11 +512,11 @@ mod tests { limit: None, }; let raw = query(deps, mock_env(), msg).unwrap(); - let members: MemberListResponse = from_slice(&raw).unwrap(); + let members: MemberListResponse = from_json(raw).unwrap(); assert_eq!(count, members.members.len()); let raw = query(deps, mock_env(), QueryMsg::TotalWeight {}).unwrap(); - let total: TotalWeightResponse = from_slice(&raw).unwrap(); + let total: TotalWeightResponse = from_json(raw).unwrap(); assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 } } @@ -669,7 +669,7 @@ mod tests { }) => { assert_eq!(contract_addr.as_str(), CW20_ADDRESS); assert_eq!(funds.len(), 0); - let parsed: Cw20ExecuteMsg = from_slice(msg).unwrap(); + let parsed: Cw20ExecuteMsg = from_json(msg).unwrap(); assert_eq!( parsed, Cw20ExecuteMsg::Transfer { @@ -692,12 +692,12 @@ mod tests { // get total from raw key let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); - let total: u64 = from_slice(&total_raw).unwrap(); + let total: u64 = from_json(total_raw).unwrap(); assert_eq!(17, total); // get member votes from raw key let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); - let member2: u64 = from_slice(&member2_raw).unwrap(); + let member2: u64 = from_json(member2_raw).unwrap(); assert_eq!(6, member2); // and execute misses @@ -852,8 +852,8 @@ mod tests { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); + let contract1 = "hook1".to_string(); + let contract2 = "hook2".to_string(); let add_msg = ExecuteMsg::AddHook { addr: contract1.clone(), @@ -920,8 +920,8 @@ mod tests { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); + let contract1 = "hook1".to_string(); + let contract2 = "hook2".to_string(); // register 2 hooks let admin_info = mock_info(INIT_ADMIN, &[]); diff --git a/packages/cw1/src/helpers.rs b/packages/cw1/src/helpers.rs index e46ecb5e2..0e9036d59 100644 --- a/packages/cw1/src/helpers.rs +++ b/packages/cw1/src/helpers.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::Cw1ExecuteMsg; @@ -19,7 +19,7 @@ impl Cw1Contract { let msg = Cw1ExecuteMsg::Execute { msgs: msgs.into() }; Ok(WasmMsg::Execute { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], } .into()) diff --git a/packages/cw20/src/helpers.rs b/packages/cw20/src/helpers.rs index 78f13a136..b388f9045 100644 --- a/packages/cw20/src/helpers.rs +++ b/packages/cw20/src/helpers.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, Uint128, + to_json_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmMsg, WasmQuery, }; @@ -22,7 +22,7 @@ impl Cw20Contract { } pub fn call>(&self, msg: T) -> StdResult { - let msg = to_binary(&msg.into())?; + let msg = to_json_binary(&msg.into())?; Ok(WasmMsg::Execute { contract_addr: self.addr().into(), msg, @@ -37,7 +37,7 @@ impl Cw20Contract { ) -> StdResult> { Ok(WasmQuery::Smart { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, } .into()) } diff --git a/packages/cw20/src/receiver.rs b/packages/cw20/src/receiver.rs index 630746e6a..34211e708 100644 --- a/packages/cw20/src/receiver.rs +++ b/packages/cw20/src/receiver.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Binary, CosmosMsg, StdResult, Uint128, WasmMsg}; /// Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg #[cw_serde] @@ -12,14 +12,14 @@ pub struct Cw20ReceiveMsg { impl Cw20ReceiveMsg { /// serializes the message - pub fn into_binary(self) -> StdResult { + pub fn into_json_binary(self) -> StdResult { let msg = ReceiverExecuteMsg::Receive(self); - to_binary(&msg) + to_json_binary(&msg) } /// creates a cosmos_msg sending this struct to the named contract pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; + let msg = self.into_json_binary()?; let execute = WasmMsg::Execute { contract_addr: contract_addr.into(), msg, diff --git a/packages/cw3/src/deposit.rs b/packages/cw3/src/deposit.rs index 8cdf0c415..029b7e4d4 100644 --- a/packages/cw3/src/deposit.rs +++ b/packages/cw3/src/deposit.rs @@ -3,7 +3,7 @@ use cw_utils::{must_pay, PaymentError}; use thiserror::Error; use cosmwasm_std::{ - to_binary, Addr, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, StdResult, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, StdResult, Uint128, WasmMsg, }; use cw20::{Denom, UncheckedDenom}; @@ -102,7 +102,7 @@ impl DepositInfo { vec![WasmMsg::Execute { contract_addr: address.to_string(), funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: depositor.to_string(), recipient: contract.to_string(), amount: *amount, @@ -128,7 +128,7 @@ impl DepositInfo { .into(), Denom::Cw20(address) => WasmMsg::Execute { contract_addr: address.to_string(), - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: depositor.to_string(), amount: self.amount, })?, diff --git a/packages/cw3/src/helpers.rs b/packages/cw3/src/helpers.rs index c360bab0f..1e8fd04ca 100644 --- a/packages/cw3/src/helpers.rs +++ b/packages/cw3/src/helpers.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::{Cw3ExecuteMsg, Vote}; use cw_utils::Expiration; @@ -22,7 +22,7 @@ impl Cw3Contract { pub fn encode_msg(&self, msg: Cw3ExecuteMsg) -> StdResult { Ok(WasmMsg::Execute { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], } .into()) diff --git a/packages/cw3/src/msg.rs b/packages/cw3/src/msg.rs index 32b9a95b8..82007e756 100644 --- a/packages/cw3/src/msg.rs +++ b/packages/cw3/src/msg.rs @@ -48,12 +48,12 @@ pub enum Vote { #[cfg(test)] mod test { use super::*; - use cosmwasm_std::to_vec; + use cosmwasm_std::to_json_vec; #[test] fn vote_encoding() { let a = Vote::Yes; - let encoded = to_vec(&a).unwrap(); + let encoded = to_json_vec(&a).unwrap(); let json = String::from_utf8_lossy(&encoded).to_string(); assert_eq!(r#""yes""#, json.as_str()); } @@ -64,7 +64,7 @@ mod test { proposal_id: 17, vote: Vote::No, }; - let encoded = to_vec(&msg).unwrap(); + let encoded = to_json_vec(&msg).unwrap(); let json = String::from_utf8_lossy(&encoded).to_string(); assert_eq!(r#"{"vote":{"proposal_id":17,"vote":"no"}}"#, json.as_str()); } diff --git a/packages/cw3/src/proposal.rs b/packages/cw3/src/proposal.rs index 4aa0c812f..a9a86ae80 100644 --- a/packages/cw3/src/proposal.rs +++ b/packages/cw3/src/proposal.rs @@ -158,7 +158,7 @@ impl Votes { // this is a helper function so Decimal works with u64 rather than Uint128 // also, we must *round up* here, as we need 8, not 7 votes to reach 50% of 15 total fn votes_needed(weight: u64, percentage: Decimal) -> u64 { - let applied = percentage * Uint128::new(PRECISION_FACTOR * weight as u128); + let applied = Uint128::new(PRECISION_FACTOR * weight as u128).mul_floor(percentage); // Divide by PRECISION_FACTOR, rounding up to the nearest integer ((applied.u128() + PRECISION_FACTOR - 1) / PRECISION_FACTOR) as u64 } diff --git a/packages/cw4/Cargo.toml b/packages/cw4/Cargo.toml index 32fc5d53a..e1f28dcbb 100644 --- a/packages/cw4/Cargo.toml +++ b/packages/cw4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw4" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "CosmWasm-4 Interface: Groups Members" diff --git a/packages/cw4/src/helpers.rs b/packages/cw4/src/helpers.rs index 57dc4d069..ee62a6830 100644 --- a/packages/cw4/src/helpers.rs +++ b/packages/cw4/src/helpers.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, WasmMsg, + to_json_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, WasmMsg, WasmQuery, }; @@ -30,7 +30,7 @@ impl Cw4Contract { fn encode_msg(&self, msg: Cw4ExecuteMsg) -> StdResult { Ok(WasmMsg::Execute { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], } .into()) @@ -56,7 +56,7 @@ impl Cw4Contract { fn encode_smart_query(&self, msg: Cw4QueryMsg) -> StdResult> { Ok(WasmQuery::Smart { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, } .into()) } diff --git a/packages/cw4/src/hook.rs b/packages/cw4/src/hook.rs index f3ce1bff2..6861c31b1 100644 --- a/packages/cw4/src/hook.rs +++ b/packages/cw4/src/hook.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Binary, CosmosMsg, StdResult, WasmMsg}; /// MemberDiff shows the old and new states for a given cw4 member /// They cannot both be None. @@ -40,14 +40,14 @@ impl MemberChangedHookMsg { } /// serializes the message - pub fn into_binary(self) -> StdResult { + pub fn into_json_binary(self) -> StdResult { let msg = MemberChangedExecuteMsg::MemberChangedHook(self); - to_binary(&msg) + to_json_binary(&msg) } /// creates a cosmos_msg sending this struct to the named contract pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; + let msg = self.into_json_binary()?; let execute = WasmMsg::Execute { contract_addr: contract_addr.into(), msg, From 119136131c8d04df0e0e9aaac8158b8c9920182b Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Thu, 29 Feb 2024 22:25:14 +0100 Subject: [PATCH 606/631] lints --- Cargo.lock | 267 ++----------------- contracts/cw3-fixed-multisig/src/contract.rs | 4 +- 2 files changed, 31 insertions(+), 240 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61b0d5c35..e415deb78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,12 +25,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -110,9 +104,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", - "ecdsa 0.16.9", + "ecdsa", "ed25519-zebra", - "k256 0.13.1", + "k256", "rand_core 0.6.4", "thiserror", ] @@ -181,18 +175,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -243,25 +225,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw-multi-test" -version = "0.16.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools 0.10.5", - "k256 0.11.6", - "prost 0.9.0", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "cw-multi-test" version = "0.20.0" @@ -275,7 +238,7 @@ dependencies = [ "cw-utils", "derivative", "itertools 0.12.1", - "prost 0.12.3", + "prost", "schemars", "serde", "sha2 0.10.8", @@ -343,7 +306,7 @@ dependencies = [ "assert_matches", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test 0.16.5", + "cw-multi-test", "cw-storage-plus", "cw-utils", "cw1", @@ -386,7 +349,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test 0.20.0", + "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", @@ -433,7 +396,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test 0.20.0", + "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", @@ -451,7 +414,7 @@ version = "1.1.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test 0.20.0", + "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", @@ -510,16 +473,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "der" version = "0.7.8" @@ -568,40 +521,18 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "easy-addr" -version = "1.1.2" -dependencies = [ - "cosmwasm-std", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der", "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] @@ -625,55 +556,25 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", + "group", + "pkcs8", "rand_core 0.6.4", - "sec1 0.7.3", + "sec1", "subtle", "zeroize", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "ff" version = "0.13.0" @@ -712,24 +613,13 @@ dependencies = [ "wasi", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", "subtle", ] @@ -758,15 +648,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.11.0" @@ -791,18 +672,6 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - [[package]] name = "k256" version = "0.13.1" @@ -810,11 +679,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "once_cell", "sha2 0.10.8", - "signature 2.2.0", + "signature", ] [[package]] @@ -835,24 +704,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.3", + "der", + "spki", ] [[package]] @@ -864,16 +723,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive 0.9.0", -] - [[package]] name = "prost" version = "0.12.3" @@ -881,20 +730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive 0.12.3", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "prost-derive", ] [[package]] @@ -934,17 +770,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -985,30 +810,16 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.8", + "base16ct", + "der", "generic-array", - "pkcs8 0.10.2", + "pkcs8", "subtle", "zeroize", ] @@ -1094,16 +905,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - [[package]] name = "signature" version = "2.2.0" @@ -1114,16 +915,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.3" @@ -1131,7 +922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der", ] [[package]] diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index dd1d56e4a..c42f8440c 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -489,7 +489,7 @@ mod tests { start_after: None, limit: None, }; - let votes: VoteListResponse = from_json(&query(deps, mock_env(), voters).unwrap()).unwrap(); + let votes: VoteListResponse = from_json(query(deps, mock_env(), voters).unwrap()).unwrap(); // Sum the weights of the Yes votes to get the tally votes .votes @@ -1021,7 +1021,7 @@ mod tests { // Proposal should now be passed let prop: ProposalResponse = from_json( - &query( + query( deps.as_ref(), env.clone(), QueryMsg::Proposal { proposal_id }, From ea24ff9633a821125379b0e362c9380ccfaad569 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Mon, 11 Mar 2024 11:14:22 +0100 Subject: [PATCH 607/631] Bumped cw-multi-test version. --- Cargo.lock | 14 ++++++++++---- Cargo.toml | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e415deb78..327e217ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "block-buffer" version = "0.9.0" @@ -151,7 +157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" dependencies = [ "base64", - "bech32", + "bech32 0.9.1", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -227,12 +233,12 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.20.0" +version = "1.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" +checksum = "c8e883315a62e08d7775f1853f86cc69f3c224e60fbc687213402852940c0d45" dependencies = [ "anyhow", - "bech32", + "bech32 0.11.0", "cosmwasm-std", "cw-storage-plus", "cw-utils", diff --git a/Cargo.toml b/Cargo.toml index 4384fd839..855e21353 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ cosmwasm-schema = "1.5" cosmwasm-std = "1.5" cw2 = "1.1" cw-controllers = "1.1" -cw-multi-test = "0.20" +cw-multi-test = "1.0.0-rc.0" cw-storage-plus = "1.2" cw-utils = "1" schemars = "0.8.15" @@ -22,13 +22,13 @@ thiserror = "1.0.4" cw1 = { path = "packages/cw1", version = "1.1.2" } cw1-whitelist = { path = "contracts/cw1-whitelist", version = "1.1.2", features = [ - "library", + "library", ] } cw20 = { path = "packages/cw20", version = "1.1.2" } cw20-base = { path = "contracts/cw20-base", version = "1.1.2", features = ["library"] } cw3 = { path = "packages/cw3", version = "1.1.2" } cw3-fixed-multisig = { path = "contracts/cw3-fixed-multisig", version = "1.1.2", features = [ - "library", + "library", ] } cw4 = { path = "packages/cw4", version = "1.1.2" } cw4-group = { path = "contracts/cw4-group", version = "1.1.2" } From 5945d567d99b665ff63344d02fd0ce809bbfc656 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Sat, 10 Feb 2024 00:55:16 +0100 Subject: [PATCH 608/631] Remove CLA and references to non-Apache 2.0 licenses Follow-up to https://github.com/CosmWasm/cw-plus/pull/835 --- CLA.md | 23 ----------------------- README.md | 5 +---- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 CLA.md diff --git a/CLA.md b/CLA.md deleted file mode 100644 index 17a701ee9..000000000 --- a/CLA.md +++ /dev/null @@ -1,23 +0,0 @@ -## Contributor License Agreement -The following terms are used throughout this agreement: - -* You - the person or legal entity including its affiliates asked to accept this agreement. An affiliate is any entity that controls or is controlled by the legal entity, or is under common control with it. -* Project - is an umbrella term that refers to any and all Confio OÃœ open source projects. -* Contribution - any type of work that is submitted to a Project, including any modifications or additions to existing work. -* Submitted - conveyed to a Project via a pull request, commit, issue, or any form of electronic, written, or verbal communication with Confio OÃœ, contributors or maintainers. - -## 1. Grant of Copyright License. - -Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers, contributors, users and to Confio OÃœ a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your contributions and such derivative works. Except for this license, You reserve all rights, title, and interest in your contributions. - -## 2. Grant of Patent License. - -Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers, contributors, users and to Confio OÃœ a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer your contributions, where such license applies only to those patent claims licensable by you that are necessarily infringed by your contribution or by combination of your contribution with the project to which this contribution was submitted. - -If any entity institutes patent litigation - including cross-claim or counterclaim in a lawsuit - against You alleging that your contribution or any project it was submitted to constitutes or is responsible for direct or contributory patent infringement, then any patent licenses granted to that entity under this agreement shall terminate as of the date such litigation is filed. - -## 3. Source of Contribution. - -Your contribution is either your original creation, based upon previous work that, to the best of your knowledge, is covered under an appropriate open source license and you have the right under that license to submit that work with modifications, whether created in whole or in part by you, or you have clearly identified the source of the contribution and any license or other restriction (like related patents, trademarks, and license agreements) of which you are personally aware. - -_Based in [GitHub's CLA](https://cla.github.com/agreement)__ \ No newline at end of file diff --git a/README.md b/README.md index 236dca30a..0e9cc5092 100644 --- a/README.md +++ b/README.md @@ -170,9 +170,6 @@ key which you can pass using `--token` flag. There's also a convenience `scripts/update_changelog.sh`, which can take a --since-tag parameter (to avoid processing the entire history). It can also auto-detect the latest version tag for you, with --latest-tag. -## Licenses +## License This repo is licensed under [Apache 2.0](./LICENSE). - -All _specifications_ will always be Apache-2.0. All contracts that are meant to be _building blocks_ will also be -Apache-2.0. This is along the lines of Open Zeppelin or other public references. From ae2e0697f169a08d3e48bdcc2f5b825cbfe1f83f Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Thu, 29 Feb 2024 22:40:49 +0100 Subject: [PATCH 609/631] add a way to statically insert mock addresses --- Cargo.lock | 10 ++++++++++ packages/easy-addr/Cargo.toml | 14 ++++++++++++++ packages/easy-addr/src/lib.rs | 15 +++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 packages/easy-addr/Cargo.toml create mode 100644 packages/easy-addr/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 327e217ee..e904de7f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -527,6 +527,16 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "easy-addr" +version = "1.1.2" +dependencies = [ + "cosmwasm-std", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ecdsa" version = "0.16.9" diff --git a/packages/easy-addr/Cargo.toml b/packages/easy-addr/Cargo.toml new file mode 100644 index 000000000..b6980c4d9 --- /dev/null +++ b/packages/easy-addr/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "easy-addr" +version.workspace = true +edition = "2021" +publish = false + +[lib] +proc-macro = true + +[dependencies] +cosmwasm-std = { workspace = true } +proc-macro2 = "1" +quote = "1" +syn = { version = "1.0.6", features = ["full", "printing", "extra-traits"] } diff --git a/packages/easy-addr/src/lib.rs b/packages/easy-addr/src/lib.rs new file mode 100644 index 000000000..385d24a38 --- /dev/null +++ b/packages/easy-addr/src/lib.rs @@ -0,0 +1,15 @@ +use cosmwasm_std::testing::mock_dependencies; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +#[proc_macro] +pub fn addr(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as syn::LitStr).value(); + let addr = mock_dependencies() + .api + .addr_make(input.as_str()) + .to_string(); + TokenStream::from(quote! {#addr}) +} From 901f1eaca88ae17e750a620f7ff536132d1c9b65 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 11 Mar 2024 16:18:08 +0100 Subject: [PATCH 610/631] update cw1 package/contracts to 2.0.0 tooling --- Cargo.lock | 1026 ----------------- contracts/cw1-subkeys/Cargo.toml | 12 +- contracts/cw1-subkeys/src/contract.rs | 22 +- contracts/cw1-whitelist/Cargo.toml | 15 +- contracts/cw1-whitelist/src/contract.rs | 30 +- .../cw1-whitelist/src/integration_tests.rs | 5 +- packages/cw1/Cargo.toml | 4 +- 7 files changed, 46 insertions(+), 1068 deletions(-) delete mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index e904de7f6..000000000 --- a/Cargo.lock +++ /dev/null @@ -1,1026 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "anyhow" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" - -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bech32" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "cosmwasm-crypto" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" -dependencies = [ - "digest 0.10.7", - "ecdsa", - "ed25519-zebra", - "k256", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-std" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" -dependencies = [ - "base64", - "bech32 0.9.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.8", - "static_assertions", - "thiserror", -] - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-controllers" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "1.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e883315a62e08d7775f1853f86cc69f3c224e60fbc687213402852940c0d45" -dependencies = [ - "anyhow", - "bech32 0.11.0", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools 0.12.1", - "prost", - "schemars", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw1" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw1-subkeys" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw1", - "cw1-whitelist", - "cw2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw1-whitelist" -version = "1.1.2" -dependencies = [ - "anyhow", - "assert_matches", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw1", - "cw2", - "derivative", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-ics20" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw3" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", - "cw20", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw3-fixed-multisig" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "cw3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw3-flex-multisig" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "cw3", - "cw3-fixed-multisig", - "cw4", - "cw4-group", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "cw4-group" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-stake" -version = "1.1.2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "easy-addr" -version = "1.1.2" -dependencies = [ - "cosmwasm-std", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "k256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.8", - "signature", -] - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" -dependencies = [ - "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[package]] -name = "schemars" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.109", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 9ecb51476..bf0e65005 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -13,19 +13,18 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] test-utils = [] [dependencies] -cosmwasm-schema = { workspace = true } -cw-utils = { workspace = true } +cosmwasm-schema = "2.0.0-rc.1" +cw-utils = "2.0.0-rc.0" cw1 = { workspace = true } -cw2 = { workspace = true } +cw2 = "2.0.0-rc.0" cw1-whitelist = { workspace = true } -cosmwasm-std = { workspace = true, features = ["staking"] } -cw-storage-plus = { workspace = true } +cosmwasm-std = { version = "2.0.0-rc.1", features = ["staking"] } +cw-storage-plus = "2.0.0-rc.0" schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } @@ -36,3 +35,4 @@ cw1-whitelist = { workspace = true, features = [ "library", "test-utils", ] } +easy-addr = { path = "../../packages/easy-addr" } diff --git a/contracts/cw1-subkeys/src/contract.rs b/contracts/cw1-subkeys/src/contract.rs index 75c59be5a..3923d81e4 100644 --- a/contracts/cw1-subkeys/src/contract.rs +++ b/contracts/cw1-subkeys/src/contract.rs @@ -479,21 +479,23 @@ mod tests { use cw2::{get_contract_version, ContractVersion}; use cw_utils::NativeBalance; + use easy_addr::addr; + use crate::state::Permissions; use std::collections::HashMap; use super::*; - const OWNER: &str = "owner"; + const OWNER: &str = addr!("owner"); - const ADMIN1: &str = "admin1"; - const ADMIN2: &str = "admin2"; + const ADMIN1: &str = addr!("admin1"); + const ADMIN2: &str = addr!("admin2"); - const SPENDER1: &str = "spender1"; - const SPENDER2: &str = "spender2"; - const SPENDER3: &str = "spender3"; - const SPENDER4: &str = "spender4"; + const SPENDER1: &str = addr!("spender1"); + const SPENDER2: &str = addr!("spender2"); + const SPENDER3: &str = addr!("spender3"); + const SPENDER4: &str = addr!("spender4"); const TOKEN: &str = "token"; const TOKEN1: &str = "token1"; @@ -2225,12 +2227,12 @@ mod tests { fn permissions_allowances_independent() { let mut deps = mock_dependencies(); - let owner = "admin0001"; + let owner = addr!("admin0001"); let admins = vec![owner.to_string()]; // spender1 has every permission to stake - let spender1 = "spender0001"; - let spender2 = "spender0002"; + let spender1 = addr!("spender0001"); + let spender2 = addr!("spender0002"); let denom = "token1"; let amount = 10000; let coin = coin(amount, denom); diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index c9f0d6c3e..991039488 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -13,18 +13,17 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] test-utils = [] [dependencies] -cosmwasm-schema = { workspace = true } -cw-utils = { workspace = true } +cosmwasm-schema = "2.0.0-rc.1" +cw-utils = "2.0.0-rc.0" cw1 = { workspace = true } -cw2 = { workspace = true } -cosmwasm-std = { workspace = true, features = ["staking"] } -cw-storage-plus = { workspace = true } +cw2 = "2.0.0-rc.0" +cosmwasm-std = { version = "2.0.0-rc.1", features = ["staking"] } +cw-storage-plus = "2.0.0-rc.0" schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } @@ -32,5 +31,7 @@ thiserror = { workspace = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -cw-multi-test = { workspace = true } +# temporary +cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test.git", branch = "v2" } derivative = "2" +easy-addr = { path = "../../packages/easy-addr" } diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index 77b085579..a6795405b 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -153,9 +153,9 @@ mod tests { fn instantiate_and_modify_config() { let mut deps = mock_dependencies(); - let alice = "alice"; - let bob = "bob"; - let carl = "carl"; + let alice = deps.api.addr_make("alice").to_string(); + let bob = deps.api.addr_make("bob").to_string(); + let carl = deps.api.addr_make("carl").to_string(); let anyone = "anyone"; @@ -186,7 +186,7 @@ mod tests { let msg = ExecuteMsg::UpdateAdmins { admins: vec![alice.to_string(), bob.to_string()], }; - let info = mock_info(alice, &[]); + let info = mock_info(&alice, &[]); execute(deps.as_mut(), mock_env(), info, msg).unwrap(); // ensure expected config @@ -197,12 +197,12 @@ mod tests { assert_eq!(query_admin_list(deps.as_ref()).unwrap(), expected); // carl cannot freeze it - let info = mock_info(carl, &[]); + let info = mock_info(&carl, &[]); let err = execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Freeze {}).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but bob can - let info = mock_info(bob, &[]); + let info = mock_info(&bob, &[]); execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Freeze {}).unwrap(); let expected = AdminListResponse { admins: vec![alice.to_string(), bob.to_string()], @@ -214,7 +214,7 @@ mod tests { let msg = ExecuteMsg::UpdateAdmins { admins: vec![alice.to_string()], }; - let info = mock_info(alice, &[]); + let info = mock_info(&alice, &[]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); } @@ -223,16 +223,16 @@ mod tests { fn execute_messages_has_proper_permissions() { let mut deps = mock_dependencies(); - let alice = "alice"; - let bob = "bob"; - let carl = "carl"; + let alice = deps.api.addr_make("alice").to_string(); + let bob = deps.api.addr_make("bob").to_string(); + let carl = deps.api.addr_make("carl").to_string(); // instantiate the contract let instantiate_msg = InstantiateMsg { admins: vec![alice.to_string(), carl.to_string()], mutable: false, }; - let info = mock_info(bob, &[]); + let info = mock_info(&bob, &[]); instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); let freeze: ExecuteMsg = ExecuteMsg::Freeze {}; @@ -254,12 +254,12 @@ mod tests { let execute_msg = ExecuteMsg::Execute { msgs: msgs.clone() }; // bob cannot execute them - let info = mock_info(bob, &[]); + let info = mock_info(&bob, &[]); let err = execute(deps.as_mut(), mock_env(), info, execute_msg.clone()).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); // but carl can - let info = mock_info(carl, &[]); + let info = mock_info(&carl, &[]); let res = execute(deps.as_mut(), mock_env(), info, execute_msg).unwrap(); assert_eq!( res.messages, @@ -272,8 +272,8 @@ mod tests { fn can_execute_query_works() { let mut deps = mock_dependencies(); - let alice = "alice"; - let bob = "bob"; + let alice = deps.api.addr_make("alice").to_string(); + let bob = deps.api.addr_make("bob").to_string(); let anyone = "anyone"; diff --git a/contracts/cw1-whitelist/src/integration_tests.rs b/contracts/cw1-whitelist/src/integration_tests.rs index 73dc1f7f0..1f1a72e15 100644 --- a/contracts/cw1-whitelist/src/integration_tests.rs +++ b/contracts/cw1-whitelist/src/integration_tests.rs @@ -2,7 +2,8 @@ use crate::msg::{AdminListResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; use anyhow::{anyhow, Result}; use assert_matches::assert_matches; use cosmwasm_std::{ - to_json_binary, Addr, CosmosMsg, Empty, QueryRequest, StdError, WasmMsg, WasmQuery, + testing::mock_dependencies, to_json_binary, Addr, CosmosMsg, Empty, QueryRequest, StdError, + WasmMsg, WasmQuery, }; use cw1::Cw1Contract; use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; @@ -37,7 +38,7 @@ pub struct Suite { impl Suite { pub fn init() -> Result { let mut app = mock_app(); - let owner = "owner".to_owned(); + let owner = mock_dependencies().api.addr_make("owner").to_string(); let cw1_id = app.store_code(contract_cw1()); Ok(Suite { app, owner, cw1_id }) diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index f9aea5555..a91fb582d 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } +cosmwasm-schema = "2.0.0-rc.1" +cosmwasm-std = "2.0.0-rc.1" schemars = { workspace = true } serde = { workspace = true } From 7eadbccd8cef7cb1ce8dfb1e154c57ac2489944b Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 4 Mar 2024 13:56:49 +0100 Subject: [PATCH 611/631] lints --- contracts/cw1-whitelist/src/contract.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/cw1-whitelist/src/contract.rs b/contracts/cw1-whitelist/src/contract.rs index a6795405b..7442fdc6b 100644 --- a/contracts/cw1-whitelist/src/contract.rs +++ b/contracts/cw1-whitelist/src/contract.rs @@ -205,7 +205,7 @@ mod tests { let info = mock_info(&bob, &[]); execute(deps.as_mut(), mock_env(), info, ExecuteMsg::Freeze {}).unwrap(); let expected = AdminListResponse { - admins: vec![alice.to_string(), bob.to_string()], + admins: vec![alice.to_string(), bob], mutable: false, }; assert_eq!(query_admin_list(deps.as_ref()).unwrap(), expected); @@ -229,7 +229,7 @@ mod tests { // instantiate the contract let instantiate_msg = InstantiateMsg { - admins: vec![alice.to_string(), carl.to_string()], + admins: vec![alice, carl.to_string()], mutable: false, }; let info = mock_info(&bob, &[]); @@ -296,11 +296,11 @@ mod tests { }); // owner can send - let res = query_can_execute(deps.as_ref(), alice.to_string(), send_msg.clone()).unwrap(); + let res = query_can_execute(deps.as_ref(), alice, send_msg.clone()).unwrap(); assert!(res.can_execute); // owner can stake - let res = query_can_execute(deps.as_ref(), bob.to_string(), staking_msg.clone()).unwrap(); + let res = query_can_execute(deps.as_ref(), bob, staking_msg.clone()).unwrap(); assert!(res.can_execute); // anyone cannot send From 01c915d5d7462948452016c8879d267c94cdb03b Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 20:29:30 +0100 Subject: [PATCH 612/631] align cw20-base --- Cargo.lock | 1016 +++++++++++++++++++++++++ Cargo.toml | 16 +- contracts/cw1-subkeys/Cargo.toml | 12 +- contracts/cw1-whitelist/Cargo.toml | 14 +- contracts/cw20-base/src/allowances.rs | 32 +- contracts/cw20-base/src/contract.rs | 300 ++++---- contracts/cw20-base/src/enumerable.rs | 29 +- packages/cw1/Cargo.toml | 4 +- 8 files changed, 1244 insertions(+), 179 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..685ed90fe --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1016 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bnum" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cosmwasm-crypto" +version = "2.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5188089c28996a446b882b61abb74dc5b90f1a4cfe26e4584a722c5f75ed4f43" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "2.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7436a7247ddcb6125dd55566687e566e7e67b8cbf27f2f9916f4bfb731f9bf4b" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7877c1debbe8dc6e8026de081c39d357579d5baa5c79d76e4428c1b26013bd38" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "2.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa51536f0c56ac14971576cff2ef4bde35d21eafcb619e16d6e89417d41e85ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "2.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb9f0cb520832e993af5cbe97bc3c163bd0c3870989e99d5f1d5499e6f28a53" +dependencies = [ + "base64", + "bech32", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cw-controllers" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3e13a92540c07dcac6f937823478b3197c5c8b1dd46f15fb2d8418e1dd4dd8" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-multi-test" +version = "2.0.0-rc.0" +source = "git+https://github.com/CosmWasm/cw-multi-test.git?branch=v2#0fee7978a70db3a14f8c9e3ce2eb5be509598277" +dependencies = [ + "anyhow", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "derivative", + "itertools 0.12.1", + "prost", + "schemars", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cw-storage-plus" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8950902b662b249447c86ddf35b70f83603aedfb5e388434f53fb4aba6a1378" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e9dfd846ca70673781742aa739bae515bc833e8cf1c033611288df5067d734" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw1" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw1-subkeys" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "cw1", + "cw1-whitelist", + "cw2", + "easy-addr", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw1-whitelist" +version = "1.1.2" +dependencies = [ + "anyhow", + "assert_matches", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus", + "cw-utils", + "cw1", + "cw2", + "derivative", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw2" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43047e25dc908fe27ff5d4cf015007ef7693d4ab89c77be415f532e5cccde6eb" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "schemars", + "serde", +] + +[[package]] +name = "cw20-base" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-ics20" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3-fixed-multisig" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "cw20-base", + "cw3", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3-flex-multisig" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "cw20-base", + "cw3", + "cw3-fixed-multisig", + "cw4", + "cw4-group", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "cw4-group" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4-stake" +version = "1.1.2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "cw4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "easy-addr" +version = "1.1.2" +dependencies = [ + "cosmwasm-std", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 855e21353..c7f80d7ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,14 @@ resolver = "2" version = "1.1.2" [workspace.dependencies] -cosmwasm-schema = "1.5" -cosmwasm-std = "1.5" -cw2 = "1.1" -cw-controllers = "1.1" -cw-multi-test = "1.0.0-rc.0" -cw-storage-plus = "1.2" -cw-utils = "1" +cosmwasm-schema = "2.0.0-rc.1" +cosmwasm-std = "2.0.0-rc.1" +cw2 = "2.0.0-rc.0" +cw-controllers = "2.0.0-rc.0" +# temporary git source +cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test.git", branch = "v2" } +cw-storage-plus = "2.0.0-rc.0" +cw-utils = "2.0.0-rc.0" schemars = "0.8.15" semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } @@ -32,6 +33,7 @@ cw3-fixed-multisig = { path = "contracts/cw3-fixed-multisig", version = "1.1.2", ] } cw4 = { path = "packages/cw4", version = "1.1.2" } cw4-group = { path = "contracts/cw4-group", version = "1.1.2" } +easy-addr = { path = "packages/easy-addr" } [profile.release.package.cw1-subkeys] codegen-units = 1 diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index bf0e65005..06b016464 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -18,13 +18,13 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = "2.0.0-rc.1" -cw-utils = "2.0.0-rc.0" +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } cw1 = { workspace = true } -cw2 = "2.0.0-rc.0" +cw2 = { workspace = true } cw1-whitelist = { workspace = true } -cosmwasm-std = { version = "2.0.0-rc.1", features = ["staking"] } -cw-storage-plus = "2.0.0-rc.0" +cosmwasm-std = { workspace = true, features = ["staking"] } +cw-storage-plus = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } @@ -35,4 +35,4 @@ cw1-whitelist = { workspace = true, features = [ "library", "test-utils", ] } -easy-addr = { path = "../../packages/easy-addr" } +easy-addr = { workspace = true } diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 991039488..2816ffa51 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -18,12 +18,12 @@ library = [] test-utils = [] [dependencies] -cosmwasm-schema = "2.0.0-rc.1" -cw-utils = "2.0.0-rc.0" +cosmwasm-schema = { workspace = true } +cw-utils = { workspace = true } cw1 = { workspace = true } -cw2 = "2.0.0-rc.0" -cosmwasm-std = { version = "2.0.0-rc.1", features = ["staking"] } -cw-storage-plus = "2.0.0-rc.0" +cw2 = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cw-storage-plus = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } @@ -31,7 +31,5 @@ thiserror = { workspace = true } [dev-dependencies] anyhow = "1" assert_matches = "1" -# temporary -cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test.git", branch = "v2" } +cw-multi-test = { workspace = true } derivative = "2" -easy-addr = { path = "../../packages/easy-addr" } diff --git a/contracts/cw20-base/src/allowances.rs b/contracts/cw20-base/src/allowances.rs index a9a4a0907..a5a488a9f 100644 --- a/contracts/cw20-base/src/allowances.rs +++ b/contracts/cw20-base/src/allowances.rs @@ -294,8 +294,8 @@ mod tests { fn increase_decrease_allowances() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); let info = mock_info(owner.as_ref(), &[]); let env = mock_env(); do_instantiate(deps.as_mut(), owner.clone(), Uint128::new(12340000)); @@ -376,9 +376,9 @@ mod tests { fn allowances_independent() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); - let spender2 = String::from("addr0003"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); + let spender2 = deps.api.addr_make("addr0003").to_string(); let info = mock_info(owner.as_ref(), &[]); let env = mock_env(); do_instantiate(deps.as_mut(), &owner, Uint128::new(12340000)); @@ -471,7 +471,7 @@ mod tests { fn no_self_allowance() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("addr0001"); + let owner = deps.api.addr_make("addr0001").to_string(); let info = mock_info(owner.as_ref(), &[]); let env = mock_env(); do_instantiate(deps.as_mut(), &owner, Uint128::new(12340000)); @@ -498,9 +498,9 @@ mod tests { #[test] fn transfer_from_respects_limits() { let mut deps = mock_dependencies_with_balance(&[]); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); - let rcpt = String::from("addr0003"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); + let rcpt = deps.api.addr_make("addr0003").to_string(); let start = Uint128::new(999999); do_instantiate(deps.as_mut(), &owner, start); @@ -580,8 +580,8 @@ mod tests { #[test] fn burn_from_respects_limits() { let mut deps = mock_dependencies_with_balance(&[]); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); let start = Uint128::new(999999); do_instantiate(deps.as_mut(), &owner, start); @@ -658,9 +658,9 @@ mod tests { #[test] fn send_from_respects_limits() { let mut deps = mock_dependencies_with_balance(&[]); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); - let contract = String::from("cool-dex"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); + let contract = deps.api.addr_make("addr0003").to_string(); let send_msg = Binary::from(r#"{"some":123}"#.as_bytes()); let start = Uint128::new(999999); @@ -764,8 +764,8 @@ mod tests { fn no_past_expiration() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("addr0001"); - let spender = String::from("addr0002"); + let owner = deps.api.addr_make("addr0001").to_string(); + let spender = deps.api.addr_make("addr0002").to_string(); let info = mock_info(owner.as_ref(), &[]); let env = mock_env(); do_instantiate(deps.as_mut(), owner.clone(), Uint128::new(12340000)); diff --git a/contracts/cw20-base/src/contract.rs b/contracts/cw20-base/src/contract.rs index 4fd8a99e0..c74281f80 100644 --- a/contracts/cw20-base/src/contract.rs +++ b/contracts/cw20-base/src/contract.rs @@ -686,13 +686,14 @@ mod tests { #[test] fn basic() { let mut deps = mock_dependencies(); + let addr = deps.api.addr_make("addr0000"); let amount = Uint128::from(11223344u128); let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), decimals: 9, initial_balances: vec![Cw20Coin { - address: String::from("addr0000"), + address: addr.to_string(), amount, }], mint: None, @@ -712,24 +713,22 @@ mod tests { total_supply: amount, } ); - assert_eq!( - get_balance(deps.as_ref(), "addr0000"), - Uint128::new(11223344) - ); + assert_eq!(get_balance(deps.as_ref(), addr), Uint128::new(11223344)); } #[test] fn mintable() { let mut deps = mock_dependencies(); + let addr = deps.api.addr_make("addr0000"); let amount = Uint128::new(11223344); - let minter = String::from("asmodat"); + let minter = deps.api.addr_make("asmodat").to_string(); let limit = Uint128::new(511223344); let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), decimals: 9, initial_balances: vec![Cw20Coin { - address: "addr0000".into(), + address: addr.to_string(), amount, }], mint: Some(MinterResponse { @@ -752,10 +751,7 @@ mod tests { total_supply: amount, } ); - assert_eq!( - get_balance(deps.as_ref(), "addr0000"), - Uint128::new(11223344) - ); + assert_eq!(get_balance(deps.as_ref(), addr), Uint128::new(11223344)); assert_eq!( query_minter(deps.as_ref()).unwrap(), Some(MinterResponse { @@ -769,18 +765,19 @@ mod tests { fn mintable_over_cap() { let mut deps = mock_dependencies(); let amount = Uint128::new(11223344); - let minter = String::from("asmodat"); + let minter = deps.api.addr_make("asmodat"); + let addr = deps.api.addr_make("addr0000"); let limit = Uint128::new(11223300); let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), decimals: 9, initial_balances: vec![Cw20Coin { - address: String::from("addr0000"), + address: addr.to_string(), amount, }], mint: Some(MinterResponse { - minter, + minter: minter.to_string(), cap: Some(limit), }), marketing: None, @@ -800,6 +797,9 @@ mod tests { #[test] fn basic() { let mut deps = mock_dependencies(); + + let marketing = deps.api.addr_make("marketing"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -809,7 +809,7 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("marketing".to_owned()), + marketing: Some(marketing.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; @@ -824,7 +824,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("marketing")), + marketing: Some(marketing), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -870,14 +870,14 @@ mod tests { fn can_mint_by_minter() { let mut deps = mock_dependencies(); - let genesis = String::from("genesis"); + let genesis = deps.api.addr_make("genesis").to_string(); let amount = Uint128::new(11223344); - let minter = String::from("asmodat"); + let minter = deps.api.addr_make("asmodat").to_string(); let limit = Uint128::new(511223344); do_instantiate_with_minter(deps.as_mut(), &genesis, amount, &minter, Some(limit)); // minter can mint coins to some winner - let winner = String::from("lucky"); + let winner = deps.api.addr_make("winner").to_string(); let prize = Uint128::new(222_222_222); let msg = ExecuteMsg::Mint { recipient: winner.clone(), @@ -915,16 +915,15 @@ mod tests { #[test] fn others_cannot_mint() { let mut deps = mock_dependencies(); - do_instantiate_with_minter( - deps.as_mut(), - &String::from("genesis"), - Uint128::new(1234), - &String::from("minter"), - None, - ); + + let genesis = deps.api.addr_make("genesis").to_string(); + let minter = deps.api.addr_make("minter").to_string(); + let winner = deps.api.addr_make("winner").to_string(); + + do_instantiate_with_minter(deps.as_mut(), &genesis, Uint128::new(1234), &minter, None); let msg = ExecuteMsg::Mint { - recipient: String::from("lucky"), + recipient: winner, amount: Uint128::new(222), }; let info = mock_info("anyone else", &[]); @@ -936,19 +935,16 @@ mod tests { #[test] fn minter_can_update_minter_but_not_cap() { let mut deps = mock_dependencies(); - let minter = String::from("minter"); + + let genesis = deps.api.addr_make("genesis").to_string(); + let minter = deps.api.addr_make("minter").to_string(); + let cap = Some(Uint128::from(3000000u128)); - do_instantiate_with_minter( - deps.as_mut(), - &String::from("genesis"), - Uint128::new(1234), - &minter, - cap, - ); + do_instantiate_with_minter(deps.as_mut(), &genesis, Uint128::new(1234), &minter, cap); - let new_minter = "new_minter"; + let new_minter = deps.api.addr_make("new_minter").to_string(); let msg = ExecuteMsg::UpdateMinter { - new_minter: Some(new_minter.to_string()), + new_minter: Some(new_minter.clone()), }; let info = mock_info(&minter, &[]); @@ -967,17 +963,15 @@ mod tests { #[test] fn others_cannot_update_minter() { let mut deps = mock_dependencies(); - let minter = String::from("minter"); - do_instantiate_with_minter( - deps.as_mut(), - &String::from("genesis"), - Uint128::new(1234), - &minter, - None, - ); + + let genesis = deps.api.addr_make("genesis").to_string(); + let minter = deps.api.addr_make("minter").to_string(); + let new_minter = deps.api.addr_make("new_minter").to_string(); + + do_instantiate_with_minter(deps.as_mut(), &genesis, Uint128::new(1234), &minter, None); let msg = ExecuteMsg::UpdateMinter { - new_minter: Some("new_minter".to_string()), + new_minter: Some(new_minter), }; let info = mock_info("not the minter", &[]); @@ -989,15 +983,13 @@ mod tests { #[test] fn unset_minter() { let mut deps = mock_dependencies(); - let minter = String::from("minter"); + + let genesis = deps.api.addr_make("genesis").to_string(); + let minter = deps.api.addr_make("minter").to_string(); + let winner = deps.api.addr_make("winner").to_string(); + let cap = None; - do_instantiate_with_minter( - deps.as_mut(), - &String::from("genesis"), - Uint128::new(1234), - &minter, - cap, - ); + do_instantiate_with_minter(deps.as_mut(), &genesis, Uint128::new(1234), &minter, cap); let msg = ExecuteMsg::UpdateMinter { new_minter: None }; @@ -1014,10 +1006,10 @@ mod tests { // Check that old minter can no longer mint. let msg = ExecuteMsg::Mint { - recipient: String::from("lucky"), + recipient: winner, amount: Uint128::new(222), }; - let info = mock_info("minter", &[]); + let info = mock_info(&minter, &[]); let env = mock_env(); let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); @@ -1026,13 +1018,17 @@ mod tests { #[test] fn no_one_mints_if_minter_unset() { let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut(), &String::from("genesis"), Uint128::new(1234)); + + let genesis = deps.api.addr_make("genesis").to_string(); + let winner = deps.api.addr_make("winner").to_string(); + + do_instantiate(deps.as_mut(), &genesis, Uint128::new(1234)); let msg = ExecuteMsg::Mint { - recipient: String::from("lucky"), + recipient: winner, amount: Uint128::new(222), }; - let info = mock_info("genesis", &[]); + let info = mock_info(&genesis, &[]); let env = mock_env(); let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); @@ -1042,9 +1038,9 @@ mod tests { fn instantiate_multiple_accounts() { let mut deps = mock_dependencies(); let amount1 = Uint128::from(11223344u128); - let addr1 = String::from("addr0001"); + let addr1 = deps.api.addr_make("addr0001").to_string(); let amount2 = Uint128::from(7890987u128); - let addr2 = String::from("addr0002"); + let addr2 = deps.api.addr_make("addr0002").to_string(); let info = mock_info("creator", &[]); let env = mock_env(); @@ -1106,7 +1102,10 @@ mod tests { #[test] fn queries_work() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let addr1 = String::from("addr0001"); + + let addr1 = deps.api.addr_make("addr0001").to_string(); + let addr2 = deps.api.addr_make("addr0002").to_string(); + let amount1 = Uint128::from(12340000u128); let expected = do_instantiate(deps.as_mut(), &addr1, amount1); @@ -1128,14 +1127,7 @@ mod tests { assert_eq!(loaded.balance, amount1); // check balance query (empty) - let data = query( - deps.as_ref(), - env, - QueryMsg::Balance { - address: String::from("addr0002"), - }, - ) - .unwrap(); + let data = query(deps.as_ref(), env, QueryMsg::Balance { address: addr2 }).unwrap(); let loaded: BalanceResponse = from_json(data).unwrap(); assert_eq!(loaded.balance, Uint128::zero()); } @@ -1143,8 +1135,8 @@ mod tests { #[test] fn transfer() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let addr1 = String::from("addr0001"); - let addr2 = String::from("addr0002"); + let addr1 = deps.api.addr_make("addr0001").to_string(); + let addr2 = deps.api.addr_make("addr0002").to_string(); let amount1 = Uint128::from(12340000u128); let transfer = Uint128::from(76543u128); let too_much = Uint128::from(12340321u128); @@ -1202,7 +1194,7 @@ mod tests { #[test] fn burn() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let addr1 = String::from("addr0001"); + let addr1 = deps.api.addr_make("addr0001").to_string(); let amount1 = Uint128::from(12340000u128); let burn = Uint128::from(76543u128); let too_much = Uint128::from(12340321u128); @@ -1250,8 +1242,8 @@ mod tests { #[test] fn send() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let addr1 = String::from("addr0001"); - let contract = String::from("addr0002"); + let addr1 = deps.api.addr_make("addr0001").to_string(); + let contract = deps.api.addr_make("contract0001").to_string(); let amount1 = Uint128::from(12340000u128); let transfer = Uint128::from(76543u128); let too_much = Uint128::from(12340321u128); @@ -1342,6 +1334,9 @@ mod tests { fn test_migrate() { let mut app = App::default(); + let sender = app.api().addr_make("sender").to_string(); + let spender = app.api().addr_make("spender").to_string(); + let cw20_id = app.store_code(cw20_contract()); let cw20_addr = app .instantiate_contract( @@ -1352,7 +1347,7 @@ mod tests { symbol: "TOKEN".to_string(), decimals: 6, initial_balances: vec![Cw20Coin { - address: "sender".to_string(), + address: sender.clone(), amount: Uint128::new(100), }], mint: None, @@ -1360,7 +1355,7 @@ mod tests { }, &[], "TOKEN", - Some("sender".to_string()), + Some(sender.clone()), ) .unwrap(); @@ -1370,7 +1365,7 @@ mod tests { .query_wasm_smart( cw20_addr.to_string(), &QueryMsg::AllAllowances { - owner: "sender".to_string(), + owner: sender.clone(), start_after: None, limit: None, }, @@ -1384,18 +1379,18 @@ mod tests { let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cw20_addr.to_string(), msg: to_json_binary(&ExecuteMsg::IncreaseAllowance { - spender: "spender".into(), + spender: spender.clone(), amount: allow1, expires: Some(expires), }) .unwrap(), funds: vec![], }); - app.execute(Addr::unchecked("sender"), msg).unwrap(); + app.execute(Addr::unchecked(&sender), msg).unwrap(); // Now migrate app.execute( - Addr::unchecked("sender"), + Addr::unchecked(&sender), CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: cw20_addr.to_string(), new_code_id: cw20_id, @@ -1410,7 +1405,7 @@ mod tests { .query_wasm_smart( cw20_addr.clone(), &QueryMsg::Balance { - address: "sender".to_string(), + address: sender.clone(), }, ) .unwrap(); @@ -1423,7 +1418,7 @@ mod tests { .query_wasm_smart( cw20_addr, &QueryMsg::AllSpenderAllowances { - spender: "spender".to_string(), + spender, start_after: None, limit: None, }, @@ -1432,7 +1427,7 @@ mod tests { assert_eq!( allowance.allowances, &[SpenderAllowanceInfo { - owner: "sender".to_string(), + owner: sender, allowance: allow1, expires }] @@ -1446,6 +1441,10 @@ mod tests { #[test] fn update_unauthorised() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let marketing = deps.api.addr_make("marketing"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1455,12 +1454,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("marketing".to_owned()), + marketing: Some(marketing.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1471,7 +1470,7 @@ mod tests { ExecuteMsg::UpdateMarketing { project: Some("New project".to_owned()), description: Some("Better description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), }, ) .unwrap_err(); @@ -1484,7 +1483,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("marketing")), + marketing: Some(marketing), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1499,6 +1498,9 @@ mod tests { #[test] fn update_project() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1508,12 +1510,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1536,7 +1538,7 @@ mod tests { MarketingInfoResponse { project: Some("New project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1551,6 +1553,9 @@ mod tests { #[test] fn clear_project() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1560,12 +1565,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1588,7 +1593,7 @@ mod tests { MarketingInfoResponse { project: None, description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1603,6 +1608,9 @@ mod tests { #[test] fn update_description() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1612,12 +1620,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1640,7 +1648,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Better description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1655,6 +1663,9 @@ mod tests { #[test] fn clear_description() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1664,12 +1675,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1692,7 +1703,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: None, - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1707,6 +1718,10 @@ mod tests { #[test] fn update_marketing() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let marketing = deps.api.addr_make("marketing"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1716,12 +1731,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1732,7 +1747,7 @@ mod tests { ExecuteMsg::UpdateMarketing { project: None, description: None, - marketing: Some("marketing".to_owned()), + marketing: Some(marketing.to_string()), }, ) .unwrap(); @@ -1744,7 +1759,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("marketing")), + marketing: Some(marketing), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1759,6 +1774,9 @@ mod tests { #[test] fn update_marketing_invalid() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1768,12 +1786,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1799,7 +1817,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -1814,6 +1832,9 @@ mod tests { #[test] fn clear_marketing() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1823,12 +1844,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1866,6 +1887,9 @@ mod tests { #[test] fn update_logo_url() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1875,12 +1899,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1899,7 +1923,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("new_url".to_owned())), } ); @@ -1914,6 +1938,9 @@ mod tests { #[test] fn update_logo_png() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1923,12 +1950,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1947,7 +1974,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Embedded), } ); @@ -1964,6 +1991,9 @@ mod tests { #[test] fn update_logo_svg() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -1973,12 +2003,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -1998,7 +2028,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Embedded), } ); @@ -2015,6 +2045,9 @@ mod tests { #[test] fn update_logo_png_oversized() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -2024,12 +2057,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -2049,7 +2082,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -2064,6 +2097,9 @@ mod tests { #[test] fn update_logo_svg_oversized() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -2073,12 +2109,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -2105,7 +2141,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -2120,6 +2156,9 @@ mod tests { #[test] fn update_logo_png_invalid() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -2129,12 +2168,12 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; - let info = mock_info("creator", &[]); + let info = mock_info(creator.as_str(), &[]); instantiate(deps.as_mut(), mock_env(), info.clone(), instantiate_msg).unwrap(); @@ -2154,7 +2193,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); @@ -2169,6 +2208,9 @@ mod tests { #[test] fn update_logo_svg_invalid() { let mut deps = mock_dependencies(); + + let creator = deps.api.addr_make("creator"); + let instantiate_msg = InstantiateMsg { name: "Cash Token".to_string(), symbol: "CASH".to_string(), @@ -2178,7 +2220,7 @@ mod tests { marketing: Some(InstantiateMarketingInfo { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some("creator".to_owned()), + marketing: Some(creator.to_string()), logo: Some(Logo::Url("url".to_owned())), }), }; @@ -2204,7 +2246,7 @@ mod tests { MarketingInfoResponse { project: Some("Project".to_owned()), description: Some("Description".to_owned()), - marketing: Some(Addr::unchecked("creator")), + marketing: Some(creator), logo: Some(LogoInfo::Url("url".to_owned())), } ); diff --git a/contracts/cw20-base/src/enumerable.rs b/contracts/cw20-base/src/enumerable.rs index 68b8fefdc..6459ba636 100644 --- a/contracts/cw20-base/src/enumerable.rs +++ b/contracts/cw20-base/src/enumerable.rs @@ -112,10 +112,10 @@ mod tests { fn query_all_owner_allowances_works() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); - let owner = String::from("owner"); + let owner = deps.api.addr_make("owner").to_string(); // these are in alphabetical order same than insert order - let spender1 = String::from("earlier"); - let spender2 = String::from("later"); + let spender1 = deps.api.addr_make("earlier").to_string(); + let spender2 = deps.api.addr_make("later").to_string(); let info = mock_info(owner.as_ref(), &[]); let env = mock_env(); @@ -176,10 +176,15 @@ mod tests { fn query_all_spender_allowances_works() { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); + let mut addresses = [ + deps.api.addr_make("owner1").to_string(), + deps.api.addr_make("owner2").to_string(), + deps.api.addr_make("spender").to_string(), + ]; + addresses.sort(); + // these are in alphabetical order same than insert order - let owner1 = String::from("owner1"); - let owner2 = String::from("owner2"); - let spender = String::from("spender"); + let [owner1, owner2, spender] = addresses; let info = mock_info(owner1.as_ref(), &[]); let env = mock_env(); @@ -257,11 +262,13 @@ mod tests { let mut deps = mock_dependencies_with_balance(&coins(2, "token")); // insert order and lexicographical order are different - let acct1 = String::from("acct01"); - let acct2 = String::from("zebra"); - let acct3 = String::from("nice"); - let acct4 = String::from("aaaardvark"); - let expected_order = [acct4.clone(), acct1.clone(), acct3.clone(), acct2.clone()]; + let acct1 = deps.api.addr_make("acct1").to_string(); + let acct2 = deps.api.addr_make("zebra").to_string(); + let acct3 = deps.api.addr_make("nice").to_string(); + let acct4 = deps.api.addr_make("aaardvark").to_string(); + + let mut expected_order = [acct1.clone(), acct2.clone(), acct3.clone(), acct4.clone()]; + expected_order.sort(); do_instantiate(deps.as_mut(), &acct1, Uint128::new(12340000)); diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index a91fb582d..f9aea5555 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" [dependencies] -cosmwasm-schema = "2.0.0-rc.1" -cosmwasm-std = "2.0.0-rc.1" +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } schemars = { workspace = true } serde = { workspace = true } From 49357445051e8c7cf05977b522d2b537c7a9dcb5 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 20:44:21 +0100 Subject: [PATCH 613/631] align cw20-ics20 --- Cargo.lock | 1 + contracts/cw20-ics20/Cargo.toml | 3 ++ contracts/cw20-ics20/src/contract.rs | 24 +++++++---- contracts/cw20-ics20/src/ibc.rs | 53 ++++++++++++------------ contracts/cw20-ics20/src/test_helpers.rs | 2 +- 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 685ed90fe..dd165f428 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,6 +367,7 @@ dependencies = [ "cw-utils", "cw2", "cw20", + "easy-addr", "schemars", "semver", "serde", diff --git a/contracts/cw20-ics20/Cargo.toml b/contracts/cw20-ics20/Cargo.toml index 6f73e6a74..b98bb509f 100644 --- a/contracts/cw20-ics20/Cargo.toml +++ b/contracts/cw20-ics20/Cargo.toml @@ -28,3 +28,6 @@ schemars = { workspace = true } semver = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } + +[dev-dependencies] +easy-addr = { workspace = true } diff --git a/contracts/cw20-ics20/src/contract.rs b/contracts/cw20-ics20/src/contract.rs index 8aa04c290..7f52cde93 100644 --- a/contracts/cw20-ics20/src/contract.rs +++ b/contracts/cw20-ics20/src/contract.rs @@ -387,6 +387,8 @@ mod test { use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{coin, coins, CosmosMsg, IbcMsg, StdError, Uint128}; + use easy_addr::addr; + use crate::state::ChannelState; use cw_utils::PaymentError; @@ -426,8 +428,8 @@ mod test { #[test] fn proper_checks_on_execute_native() { - let foobar = "foobar"; - let foreign = "foreign-address"; + let foobar = addr!("foobar"); + let foreign = addr!("foreign-address"); let send_channel = "channel-5"; let mut deps = setup(&[send_channel, "channel-10"], &[]); @@ -491,9 +493,9 @@ mod test { #[test] fn proper_checks_on_execute_cw20() { let send_channel = "channel-15"; - let cw20_addr = "my-token"; - let foreign = "foreign-address"; - let sender = "my-account"; + let cw20_addr = addr!("my-token"); + let foreign = addr!("foreign-address"); + let sender = addr!("my-account"); let mut deps = setup(&["channel-3", send_channel], &[(cw20_addr, 123456)]); let transfer = TransferMsg { @@ -542,15 +544,18 @@ mod test { let send_channel = "channel-15"; let mut deps = setup(&[send_channel], &[]); - let cw20_addr = "my-token"; + let my_account = addr!("my-account"); + let cw20_addr = addr!("my-token"); + let foreign = addr!("foreign-address"); + let transfer = TransferMsg { channel: send_channel.to_string(), - remote_address: "foreign-address".to_string(), + remote_address: foreign.to_string(), timeout: Some(7777), memo: None, }; let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { - sender: "my-account".into(), + sender: my_account.into(), amount: Uint128::new(888777666), msg: to_json_binary(&transfer).unwrap(), }); @@ -578,13 +583,14 @@ mod test { fn v3_migration_works() { // basic state with one channel let send_channel = "channel-15"; - let cw20_addr = "my-token"; + let cw20_addr = addr!("my-token"); let native = "ucosm"; let mut deps = setup(&[send_channel], &[(cw20_addr, 123456)]); // mock that we sent some tokens in both native and cw20 (TODO: cw20) // balances set high deps.querier + .bank .update_balance(MOCK_CONTRACT_ADDR, coins(50000, native)); // pretend this is an old contract - set version explicitly set_contract_version(deps.as_mut().storage, CONTRACT_NAME, MIGRATE_VERSION_3).unwrap(); diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index fdc87726b..11fd62a51 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -201,13 +201,13 @@ pub fn ibc_packet_receive( let packet = msg.packet; do_ibc_packet_receive(deps, &packet).or_else(|err| { - Ok(IbcReceiveResponse::new() - .set_ack(ack_fail(err.to_string())) - .add_attributes(vec![ + Ok( + IbcReceiveResponse::new(ack_fail(err.to_string())).add_attributes(vec![ attr("action", "receive"), attr("success", "false"), attr("error", err.to_string()), - ])) + ]), + ) }) } @@ -265,8 +265,7 @@ fn do_ibc_packet_receive( let mut submsg = SubMsg::reply_on_error(send, RECEIVE_ID); submsg.gas_limit = gas_limit; - let res = IbcReceiveResponse::new() - .set_ack(ack_success()) + let res = IbcReceiveResponse::new(ack_success()) .add_submessage(submsg) .add_attribute("action", "receive") .add_attribute("sender", msg.sender) @@ -403,9 +402,11 @@ mod test { use crate::contract::{execute, migrate, query_channel}; use crate::msg::{ExecuteMsg, MigrateMsg, TransferMsg}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{coins, to_json_vec, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; + use cosmwasm_std::{coins, to_json_vec, Addr, IbcEndpoint, IbcMsg, IbcTimeout, Timestamp}; use cw20::Cw20ReceiveMsg; + use easy_addr::addr; + #[test] fn check_ack_json() { let success = Ics20Ack::Result(b"1".into()); @@ -496,11 +497,11 @@ mod test { #[test] fn send_receive_cw20() { let send_channel = "channel-9"; - let cw20_addr = "token-addr"; - let cw20_denom = "cw20:token-addr"; - let local_rcpt = "local-rcpt"; - let local_sender = "local-sender"; - let remote_rcpt = "remote-rcpt"; + let cw20_addr = addr!("token-addr"); + let cw20_denom = concat!("cw20:", addr!("token-addr")); + let local_rcpt = addr!("local-rcpt"); + let local_sender = addr!("local-sender"); + let remote_rcpt = addr!("remote-rcpt"); let gas_limit = 1234567; let mut deps = setup( &["channel-1", "channel-7", send_channel], @@ -513,10 +514,10 @@ mod test { mock_receive_packet(send_channel, 1876543210, cw20_denom, local_rcpt); // cannot receive this denom yet - let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); + let msg = IbcPacketReceiveMsg::new(recv_packet.clone(), Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); @@ -559,21 +560,21 @@ mod test { assert_eq!(state.total_sent, vec![Amount::cw20(987654321, cw20_addr)]); // cannot receive more than we sent - let msg = IbcPacketReceiveMsg::new(recv_high_packet); + let msg = IbcPacketReceiveMsg::new(recv_high_packet, Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); assert_eq!(ack, no_funds); // we can receive less than we sent - let msg = IbcPacketReceiveMsg::new(recv_packet); + let msg = IbcPacketReceiveMsg::new(recv_packet, Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert_eq!(1, res.messages.len()); assert_eq!( cw20_payment(876543210, cw20_addr, local_rcpt, Some(gas_limit)), res.messages[0] ); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); assert!(matches!(ack, Ics20Ack::Result(_))); // TODO: we need to call the reply block @@ -596,10 +597,10 @@ mod test { let recv_high_packet = mock_receive_packet(send_channel, 1876543210, denom, "local-rcpt"); // cannot receive this denom yet - let msg = IbcPacketReceiveMsg::new(recv_packet.clone()); + let msg = IbcPacketReceiveMsg::new(recv_packet.clone(), Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); let no_funds = Ics20Ack::Error(ContractError::InsufficientFunds {}.to_string()); assert_eq!(ack, no_funds); @@ -619,21 +620,21 @@ mod test { assert_eq!(state.total_sent, vec![Amount::native(987654321, denom)]); // cannot receive more than we sent - let msg = IbcPacketReceiveMsg::new(recv_high_packet); + let msg = IbcPacketReceiveMsg::new(recv_high_packet, Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert!(res.messages.is_empty()); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); assert_eq!(ack, no_funds); // we can receive less than we sent - let msg = IbcPacketReceiveMsg::new(recv_packet); + let msg = IbcPacketReceiveMsg::new(recv_packet, Addr::unchecked("")); let res = ibc_packet_receive(deps.as_mut(), mock_env(), msg).unwrap(); assert_eq!(1, res.messages.len()); assert_eq!( native_payment(876543210, denom, "local-rcpt"), res.messages[0] ); - let ack: Ics20Ack = from_json(res.acknowledgement).unwrap(); + let ack: Ics20Ack = from_json(res.acknowledgement.unwrap()).unwrap(); assert!(matches!(ack, Ics20Ack::Result(_))); // only need to call reply block on error case @@ -647,7 +648,7 @@ mod test { #[test] fn check_gas_limit_handles_all_cases() { let send_channel = "channel-9"; - let allowed = "foobar"; + let allowed = addr!("foobar"); let allowed_gas = 777666; let mut deps = setup(&[send_channel], &[(allowed, allowed_gas)]); @@ -656,7 +657,7 @@ mod test { assert_eq!(limit, Some(allowed_gas)); // non-allow list will error - let random = "tokenz"; + let random = addr!("tokenz"); check_gas_limit(deps.as_ref(), &Amount::cw20(500, random)).unwrap_err(); // add default_gas_limit diff --git a/contracts/cw20-ics20/src/test_helpers.rs b/contracts/cw20-ics20/src/test_helpers.rs index 105079314..b69db28d7 100644 --- a/contracts/cw20-ics20/src/test_helpers.rs +++ b/contracts/cw20-ics20/src/test_helpers.rs @@ -72,7 +72,7 @@ pub fn setup( let instantiate_msg = InitMsg { default_gas_limit: None, default_timeout: DEFAULT_TIMEOUT, - gov_contract: "gov".to_string(), + gov_contract: deps.api.addr_make("gov").to_string(), allowlist, }; let info = mock_info("anyone", &[]); From 5e74fe62e46e34882cedf2d1fe782235278a9f15 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 20:53:22 +0100 Subject: [PATCH 614/631] align cw3 contracts --- Cargo.lock | 2 ++ contracts/cw3-fixed-multisig/Cargo.toml | 1 + contracts/cw3-fixed-multisig/src/contract.rs | 20 +++++++------ .../src/integration_tests.rs | 10 +++---- contracts/cw3-flex-multisig/Cargo.toml | 1 + contracts/cw3-flex-multisig/src/contract.rs | 30 +++++++++---------- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd165f428..09dc86350 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,6 +400,7 @@ dependencies = [ "cw20", "cw20-base", "cw3", + "easy-addr", "schemars", "serde", "thiserror", @@ -421,6 +422,7 @@ dependencies = [ "cw3-fixed-multisig", "cw4", "cw4-group", + "easy-addr", "schemars", "serde", "thiserror", diff --git a/contracts/cw3-fixed-multisig/Cargo.toml b/contracts/cw3-fixed-multisig/Cargo.toml index e6463be6c..c27002e3a 100644 --- a/contracts/cw3-fixed-multisig/Cargo.toml +++ b/contracts/cw3-fixed-multisig/Cargo.toml @@ -31,3 +31,4 @@ thiserror = { workspace = true } cw20 = { workspace = true } cw20-base = { workspace = true } cw-multi-test = { workspace = true } +easy-addr = { workspace = true } diff --git a/contracts/cw3-fixed-multisig/src/contract.rs b/contracts/cw3-fixed-multisig/src/contract.rs index c42f8440c..9f247434e 100644 --- a/contracts/cw3-fixed-multisig/src/contract.rs +++ b/contracts/cw3-fixed-multisig/src/contract.rs @@ -421,6 +421,8 @@ mod tests { use cw2::{get_contract_version, ContractVersion}; use cw_utils::{Duration, Threshold}; + use easy_addr::addr; + use crate::msg::Voter; use super::*; @@ -437,15 +439,15 @@ mod tests { env } - const OWNER: &str = "admin0001"; - const VOTER1: &str = "voter0001"; - const VOTER2: &str = "voter0002"; - const VOTER3: &str = "voter0003"; - const VOTER4: &str = "voter0004"; - const VOTER5: &str = "voter0005"; - const VOTER6: &str = "voter0006"; - const NOWEIGHT_VOTER: &str = "voterxxxx"; - const SOMEBODY: &str = "somebody"; + const OWNER: &str = addr!("admin0001"); + const VOTER1: &str = addr!("voter0001"); + const VOTER2: &str = addr!("voter0002"); + const VOTER3: &str = addr!("voter0003"); + const VOTER4: &str = addr!("voter0004"); + const VOTER5: &str = addr!("voter0005"); + const VOTER6: &str = addr!("voter0006"); + const NOWEIGHT_VOTER: &str = addr!("voterxxxx"); + const SOMEBODY: &str = addr!("somebody"); fn voter>(addr: T, weight: u64) -> Voter { Voter { diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index f8c344f7c..dc3c971eb 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use cosmwasm_std::{to_json_binary, Addr, Empty, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Empty, Uint128, WasmMsg}; use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; @@ -36,9 +36,9 @@ fn cw3_controls_cw20() { // setup cw3 multisig with 3 accounts let cw3_id = router.store_code(contract_cw3_fixed_multisig()); - let addr1 = Addr::unchecked("addr1"); - let addr2 = Addr::unchecked("addr2"); - let addr3 = Addr::unchecked("addr3"); + let addr1 = router.api().addr_make("addr1"); + let addr2 = router.api().addr_make("addr2"); + let addr3 = router.api().addr_make("addr3"); let cw3_instantiate_msg = InstantiateMsg { voters: vec![ Voter { @@ -95,7 +95,7 @@ fn cw3_controls_cw20() { .unwrap(); // mint some cw20 tokens according to proposal result - let mint_recipient = Addr::unchecked("recipient"); + let mint_recipient = router.api().addr_make("mint_recipient"); let mint_amount = Uint128::new(1000); let cw20_mint_msg = cw20_base::msg::ExecuteMsg::Mint { recipient: mint_recipient.to_string(), diff --git a/contracts/cw3-flex-multisig/Cargo.toml b/contracts/cw3-flex-multisig/Cargo.toml index 0f062b690..12d104f02 100644 --- a/contracts/cw3-flex-multisig/Cargo.toml +++ b/contracts/cw3-flex-multisig/Cargo.toml @@ -34,3 +34,4 @@ thiserror = { workspace = true } cw4-group = { workspace = true } cw-multi-test = { workspace = true } cw20-base = { workspace = true } +easy-addr = { workspace = true } diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index e0e731c2e..63c6cc398 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -499,15 +499,18 @@ mod tests { }; use cw_utils::{Duration, Threshold}; + use easy_addr::addr; + use super::*; - const OWNER: &str = "admin0001"; - const VOTER1: &str = "voter0001"; - const VOTER2: &str = "voter0002"; - const VOTER3: &str = "voter0003"; - const VOTER4: &str = "voter0004"; - const VOTER5: &str = "voter0005"; - const SOMEBODY: &str = "somebody"; + const OWNER: &str = addr!("admin0001"); + const VOTER1: &str = addr!("voter0001"); + const VOTER2: &str = addr!("voter0002"); + const VOTER3: &str = addr!("voter0003"); + const VOTER4: &str = addr!("voter0004"); + const VOTER5: &str = addr!("voter0005"); + const SOMEBODY: &str = addr!("somebody"); + const NEWBIE: &str = addr!("newbie"); fn member>(addr: T, weight: u64) -> Member { Member { @@ -1683,10 +1686,9 @@ mod tests { // updates VOTER2 power to 21 -> with snapshot, vote doesn't pass proposal // adds NEWBIE with 2 power -> with snapshot, invalid vote // removes VOTER3 -> with snapshot, can vote on proposal - let newbie: &str = "newbie"; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], - add: vec![member(VOTER2, 21), member(newbie, 2)], + add: vec![member(VOTER2, 21), member(NEWBIE, 2)], }; app.execute_contract(Addr::unchecked(OWNER), group_addr, &update_msg, &[]) .unwrap(); @@ -1735,7 +1737,7 @@ mod tests { // newbie cannot vote let err = app - .execute_contract(Addr::unchecked(newbie), flex_addr.clone(), &yes_vote, &[]) + .execute_contract(Addr::unchecked(NEWBIE), flex_addr.clone(), &yes_vote, &[]) .unwrap_err(); assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); @@ -1921,10 +1923,9 @@ mod tests { app.update_block(|block| block.height += 2); // admin changes the group (3 -> 0, 2 -> 9, 0 -> 29) - total = 56, require 29 to pass - let newbie: &str = "newbie"; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], - add: vec![member(VOTER2, 9), member(newbie, 29)], + add: vec![member(VOTER2, 9), member(NEWBIE, 29)], }; app.execute_contract(Addr::unchecked(OWNER), group_addr, &update_msg, &[]) .unwrap(); @@ -1945,7 +1946,7 @@ mod tests { // new proposal can be passed single-handedly by newbie let proposal = pay_somebody_proposal(); let res = app - .execute_contract(Addr::unchecked(newbie), flex_addr.clone(), &proposal, &[]) + .execute_contract(Addr::unchecked(NEWBIE), flex_addr.clone(), &proposal, &[]) .unwrap(); // Get the proposal id from the logs let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -2006,10 +2007,9 @@ mod tests { app.update_block(|block| block.height += 2); // admin changes the group (3 -> 0, 2 -> 9, 0 -> 28) - total = 55, require 28 to pass - let newbie: &str = "newbie"; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], - add: vec![member(VOTER2, 9), member(newbie, 29)], + add: vec![member(VOTER2, 9), member(NEWBIE, 29)], }; app.execute_contract(Addr::unchecked(OWNER), group_addr, &update_msg, &[]) .unwrap(); From b3833a080b71dd9c4bea1bd304e01df560352ab1 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 20:59:38 +0100 Subject: [PATCH 615/631] align cw4 contracts --- Cargo.lock | 2 ++ contracts/cw4-group/Cargo.toml | 3 +++ contracts/cw4-group/src/tests.rs | 18 ++++++++++-------- contracts/cw4-stake/Cargo.toml | 3 +++ contracts/cw4-stake/src/contract.rs | 22 +++++++++++----------- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09dc86350..f7f55676e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,6 +450,7 @@ dependencies = [ "cw-utils", "cw2", "cw4", + "easy-addr", "schemars", "serde", "thiserror", @@ -467,6 +468,7 @@ dependencies = [ "cw2", "cw20", "cw4", + "easy-addr", "schemars", "serde", "thiserror", diff --git a/contracts/cw4-group/Cargo.toml b/contracts/cw4-group/Cargo.toml index 9cb692c02..646de3e9a 100644 --- a/contracts/cw4-group/Cargo.toml +++ b/contracts/cw4-group/Cargo.toml @@ -34,3 +34,6 @@ cosmwasm-std = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } + +[dev-dependencies] +easy-addr = { workspace = true } diff --git a/contracts/cw4-group/src/tests.rs b/contracts/cw4-group/src/tests.rs index 202354a39..884d7ab63 100644 --- a/contracts/cw4-group/src/tests.rs +++ b/contracts/cw4-group/src/tests.rs @@ -10,10 +10,12 @@ use crate::msg::{ExecuteMsg, InstantiateMsg}; use crate::state::{ADMIN, HOOKS}; use crate::ContractError; -const INIT_ADMIN: &str = "juan"; -const USER1: &str = "somebody"; -const USER2: &str = "else"; -const USER3: &str = "funny"; +use easy_addr::addr; + +const INIT_ADMIN: &str = addr!("juan"); +const USER1: &str = addr!("somebody"); +const USER2: &str = addr!("else"); +const USER3: &str = addr!("funny"); fn set_up(deps: DepsMut) { let msg = InstantiateMsg { @@ -278,8 +280,8 @@ fn add_remove_hooks() { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = "hook1".to_string(); - let contract2 = "hook2".to_string(); + let contract1 = deps.api.addr_make("hook1").to_string(); + let contract2 = deps.api.addr_make("hook2").to_string(); let add_msg = ExecuteMsg::AddHook { addr: contract1.clone(), @@ -346,8 +348,8 @@ fn hooks_fire() { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = "hook1".to_string(); - let contract2 = "hook2".to_string(); + let contract1 = deps.api.addr_make("hook1").to_string(); + let contract2 = deps.api.addr_make("hook2").to_string(); // register 2 hooks let admin_info = mock_info(INIT_ADMIN, &[]); diff --git a/contracts/cw4-stake/Cargo.toml b/contracts/cw4-stake/Cargo.toml index 006c83695..c38e466a6 100644 --- a/contracts/cw4-stake/Cargo.toml +++ b/contracts/cw4-stake/Cargo.toml @@ -35,3 +35,6 @@ cosmwasm-std = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } + +[dev-dependencies] +easy-addr = { workspace = true } diff --git a/contracts/cw4-stake/src/contract.rs b/contracts/cw4-stake/src/contract.rs index 4b12df0ea..41d92b4f6 100644 --- a/contracts/cw4-stake/src/contract.rs +++ b/contracts/cw4-stake/src/contract.rs @@ -368,17 +368,19 @@ mod tests { use crate::error::ContractError; + use easy_addr::addr; + use super::*; - const INIT_ADMIN: &str = "juan"; - const USER1: &str = "somebody"; - const USER2: &str = "else"; - const USER3: &str = "funny"; + const INIT_ADMIN: &str = addr!("juan"); + const USER1: &str = addr!("someone"); + const USER2: &str = addr!("else"); + const USER3: &str = addr!("funny"); const DENOM: &str = "stake"; const TOKENS_PER_WEIGHT: Uint128 = Uint128::new(1_000); const MIN_BOND: Uint128 = Uint128::new(5_000); const UNBONDING_BLOCKS: u64 = 100; - const CW20_ADDRESS: &str = "wasm1234567890"; + const CW20_ADDRESS: &str = addr!("wasm"); fn default_instantiate(deps: DepsMut) { do_instantiate( @@ -601,8 +603,6 @@ mod tests { err, ContractError::Std(StdError::overflow(OverflowError::new( OverflowOperation::Sub, - 5000, - 5100 ))) ); } @@ -852,8 +852,8 @@ mod tests { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = "hook1".to_string(); - let contract2 = "hook2".to_string(); + let contract1 = deps.api.addr_make("hook1").to_string(); + let contract2 = deps.api.addr_make("hook2").to_string(); let add_msg = ExecuteMsg::AddHook { addr: contract1.clone(), @@ -920,8 +920,8 @@ mod tests { let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); assert!(hooks.hooks.is_empty()); - let contract1 = "hook1".to_string(); - let contract2 = "hook2".to_string(); + let contract1 = deps.api.addr_make("hook1").to_string(); + let contract2 = deps.api.addr_make("hook2").to_string(); // register 2 hooks let admin_info = mock_info(INIT_ADMIN, &[]); From 3854e26f531a9afd67d7af665b13d88da1af665c Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 21:25:29 +0100 Subject: [PATCH 616/631] fix wasm build of cw20-ics20 --- contracts/cw20-ics20/src/ibc.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/contracts/cw20-ics20/src/ibc.rs b/contracts/cw20-ics20/src/ibc.rs index 11fd62a51..086f0fc14 100644 --- a/contracts/cw20-ics20/src/ibc.rs +++ b/contracts/cw20-ics20/src/ibc.rs @@ -6,9 +6,10 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::entry_point; use cosmwasm_std::{ attr, from_json, to_json_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, - IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, - IbcReceiveResponse, Reply, Response, SubMsg, SubMsgResult, Uint128, WasmMsg, + Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, + IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, + IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, SubMsg, + SubMsgResult, Uint128, WasmMsg, }; use crate::amount::Amount; @@ -131,9 +132,9 @@ pub fn ibc_channel_open( _deps: DepsMut, _env: Env, msg: IbcChannelOpenMsg, -) -> Result<(), ContractError> { +) -> Result, ContractError> { enforce_order_and_version(msg.channel(), msg.counterparty_version())?; - Ok(()) + Ok(None) } #[cfg_attr(not(feature = "library"), entry_point)] From 3e7100071850b608035e715f2b948d4ea296430a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 21:35:49 +0100 Subject: [PATCH 617/631] CI: update cosmwasm-check --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 166088745..0195862a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -455,7 +455,7 @@ jobs: - run: name: Install cosmwasm-check # Uses --debug for compilation speed - command: cargo install --locked --debug --version 1.4.0 cosmwasm-check + command: cargo install --locked --debug --version 2.0.0-rc.1 cosmwasm-check - save_cache: paths: - /usr/local/cargo/registry From 0f3f89f5d263f36863ca9a910ebb7d1482615a37 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 5 Mar 2024 21:42:45 +0100 Subject: [PATCH 618/631] CI: bump compiler version --- .circleci/config.yml | 92 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0195862a8..534f7ef77 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,7 @@ workflows: jobs: contract_cw1_subkeys: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw1-subkeys steps: - checkout: @@ -50,7 +50,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-subkeys-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-subkeys-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -63,11 +63,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-subkeys-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-subkeys-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw1_whitelist: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw1-whitelist steps: - checkout: @@ -77,7 +77,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw1-whitelist-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw1-whitelist-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -90,11 +90,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw1-whitelist-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw1-whitelist-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_fixed_multisig: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw3-fixed-multisig steps: - checkout: @@ -104,7 +104,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-fixed-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-fixed-multisig-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -117,11 +117,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-fixed-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-fixed-multisig-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw3_flex_multisig: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw3-flex-multisig steps: - checkout: @@ -131,7 +131,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw3-flex-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw3-flex-multisig-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -144,11 +144,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw3-flex-multisig-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw3-flex-multisig-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_group: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw4-group steps: - checkout: @@ -158,7 +158,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-group-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-group-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -171,11 +171,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-group-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-group-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw4_stake: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw4-stake steps: - checkout: @@ -185,7 +185,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw4-stake-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw4-stake-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -198,11 +198,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw4-stake-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw4-stake-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_base: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw20-base steps: - checkout: @@ -212,7 +212,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-base-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-base-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -225,11 +225,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-base-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-base-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} contract_cw20_ics20: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/contracts/cw20-ics20 steps: - checkout: @@ -239,7 +239,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-cw20-ics20-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-cw20-ics20-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -252,11 +252,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-cw20-ics20-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-cw20-ics20-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} package_cw1: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/packages/cw1 steps: - checkout: @@ -266,7 +266,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -280,11 +280,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1:1.76.0-{{ checksum "~/project/Cargo.lock" }} package_cw3: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/packages/cw3 steps: - checkout: @@ -294,7 +294,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw3:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw3:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -308,11 +308,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw3:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw3:1.76.0-{{ checksum "~/project/Cargo.lock" }} package_cw4: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/packages/cw4 steps: - checkout: @@ -322,7 +322,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw4:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw4:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -336,11 +336,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw4:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw4:1.76.0-{{ checksum "~/project/Cargo.lock" }} package_cw20: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/packages/cw20 steps: - checkout: @@ -350,7 +350,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw20:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw20:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -364,11 +364,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw20:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw20:1.76.0-{{ checksum "~/project/Cargo.lock" }} package_cw1155: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project/packages/cw1155 steps: - checkout: @@ -378,7 +378,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-cw1155:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-v2-cw1155:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Build library for native target command: cargo build --locked @@ -392,11 +392,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-v2-cw1155:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-v2-cw1155:1.76.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 steps: - checkout - run: @@ -404,7 +404,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.67.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.76.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -423,7 +423,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.67.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.76.0-{{ 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 @@ -431,7 +431,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 steps: - checkout: path: ~/project @@ -440,7 +440,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -460,7 +460,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.67.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.76.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm @@ -528,7 +528,7 @@ jobs: build_and_upload_schemas: docker: - - image: rust:1.67.0 + - image: rust:1.76.0 working_directory: ~/project steps: - checkout: From b765e628c5d8e5c92a1cb06e6e3c93f3e67ddece Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Mon, 11 Mar 2024 11:45:15 +0100 Subject: [PATCH 619/631] Bumped cw-multi-test version. --- Cargo.lock | 12 ++++++++++-- Cargo.toml | 3 +-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7f55676e..a8d61174b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "block-buffer" version = "0.9.0" @@ -150,7 +156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cb9f0cb520832e993af5cbe97bc3c163bd0c3870989e99d5f1d5499e6f28a53" dependencies = [ "base64", - "bech32", + "bech32 0.9.1", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -227,9 +233,11 @@ dependencies = [ [[package]] name = "cw-multi-test" version = "2.0.0-rc.0" -source = "git+https://github.com/CosmWasm/cw-multi-test.git?branch=v2#0fee7978a70db3a14f8c9e3ce2eb5be509598277" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5639954f5e312c5d75b9c55411333a517db2622c7d0b6180058b469b12a58de3" dependencies = [ "anyhow", + "bech32 0.11.0", "cosmwasm-std", "cw-storage-plus", "cw-utils", diff --git a/Cargo.toml b/Cargo.toml index c7f80d7ec..a4cefdccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,7 @@ cosmwasm-schema = "2.0.0-rc.1" cosmwasm-std = "2.0.0-rc.1" cw2 = "2.0.0-rc.0" cw-controllers = "2.0.0-rc.0" -# temporary git source -cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test.git", branch = "v2" } +cw-multi-test = "2.0.0-rc.0" cw-storage-plus = "2.0.0-rc.0" cw-utils = "2.0.0-rc.0" schemars = "0.8.15" From 1cc648d8c46ec284c9d2ff50b39f08a81f2770a7 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 20 Mar 2024 14:44:51 +0100 Subject: [PATCH 620/631] Upgraded dependencies to 2.0.0 except cw-multi-test. --- Cargo.lock | 52 ++++++++++++++++++++++++++-------------------------- Cargo.toml | 14 +++++++------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8d61174b..f446c3875 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "assert_matches" @@ -105,9 +105,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" -version = "2.0.0-rc.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5188089c28996a446b882b61abb74dc5b90f1a4cfe26e4584a722c5f75ed4f43" +checksum = "3e5fd9485d4f1f4330547a8a5aaf0958c68b4d620975ded2c15f2ed5c49e8e74" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -118,18 +118,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "2.0.0-rc.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7436a7247ddcb6125dd55566687e566e7e67b8cbf27f2f9916f4bfb731f9bf4b" +checksum = "d692944045feabbf46c75e8f072024bb885a7742025e40d46913296fe9fbbd06" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "2.0.0-rc.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7877c1debbe8dc6e8026de081c39d357579d5baa5c79d76e4428c1b26013bd38" +checksum = "a67c099aba9e334bbc1fc8037fe8e7ba91d06b215d9ffa7af91893c44aa420c6" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "2.0.0-rc.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa51536f0c56ac14971576cff2ef4bde35d21eafcb619e16d6e89417d41e85ed" +checksum = "8a2bb09168f6e86bf583361fdb0a0fed2625652e9edcfce731cb55ef4cb8de3d" dependencies = [ "proc-macro2", "quote", @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "2.0.0-rc.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb9f0cb520832e993af5cbe97bc3c163bd0c3870989e99d5f1d5499e6f28a53" +checksum = "464f484b3f289935a41e374560c66c59a8f881aefc74742558e42008f1b0b7f3" dependencies = [ "base64", "bech32 0.9.1", @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "2.0.0-rc.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3e13a92540c07dcac6f937823478b3197c5c8b1dd46f15fb2d8418e1dd4dd8" +checksum = "50c1804013d21060b994dea28a080f9eab78a3bcb6b617f05e7634b0600bf7b1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -232,9 +232,9 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "2.0.0-rc.0" +version = "2.0.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5639954f5e312c5d75b9c55411333a517db2622c7d0b6180058b469b12a58de3" +checksum = "a6e83a1453fc6a9348a67a24ada22a5a2fae675305844bb85c2a436c930cffdd" dependencies = [ "anyhow", "bech32 0.11.0", @@ -252,9 +252,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "2.0.0-rc.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8950902b662b249447c86ddf35b70f83603aedfb5e388434f53fb4aba6a1378" +checksum = "f13360e9007f51998d42b1bc6b7fa0141f74feae61ed5fd1e5b0a89eec7b5de1" dependencies = [ "cosmwasm-std", "schemars", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "cw-utils" -version = "2.0.0-rc.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e9dfd846ca70673781742aa739bae515bc833e8cf1c033611288df5067d734" +checksum = "07dfee7f12f802431a856984a32bce1cb7da1e6c006b5409e3981035ce562dec" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "cw2" -version = "2.0.0-rc.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43047e25dc908fe27ff5d4cf015007ef7693d4ab89c77be415f532e5cccde6eb" +checksum = "b04852cd38f044c0751259d5f78255d07590d136b8a86d4e09efdd7666bd6d27" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -980,18 +980,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a4cefdccb..278f32735 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,13 @@ resolver = "2" version = "1.1.2" [workspace.dependencies] -cosmwasm-schema = "2.0.0-rc.1" -cosmwasm-std = "2.0.0-rc.1" -cw2 = "2.0.0-rc.0" -cw-controllers = "2.0.0-rc.0" -cw-multi-test = "2.0.0-rc.0" -cw-storage-plus = "2.0.0-rc.0" -cw-utils = "2.0.0-rc.0" +cosmwasm-schema = "2.0.0" +cosmwasm-std = "2.0.0" +cw2 = "2.0.0" +cw-controllers = "2.0.0" +cw-multi-test = "2.0.0-rc.2" +cw-storage-plus = "2.0.0" +cw-utils = "2.0.0" schemars = "0.8.15" semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } From bac1a9815ea9f46e41d4ff049b008fddb17d0f5f Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 20 Mar 2024 15:17:24 +0100 Subject: [PATCH 621/631] bump cw-plus to 2.0.0-rc.0 --- Cargo.lock | 44 +++++++++++++++--------------- Cargo.toml | 18 ++++++------ contracts/cw1-subkeys/Cargo.toml | 2 +- contracts/cw1-whitelist/Cargo.toml | 2 +- packages/cw1/Cargo.toml | 2 +- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f446c3875..6f9d1bd07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,7 +276,7 @@ dependencies = [ [[package]] name = "cw1" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -286,7 +286,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -304,7 +304,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "anyhow", "assert_matches", @@ -338,7 +338,7 @@ dependencies = [ [[package]] name = "cw20" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -349,7 +349,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -384,7 +384,7 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -397,7 +397,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -416,7 +416,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -438,7 +438,7 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -466,7 +466,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -532,7 +532,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "easy-addr" -version = "1.1.2" +version = "2.0.0-rc.0" dependencies = [ "cosmwasm-std", "proc-macro2", @@ -719,9 +719,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "pkcs8" @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -762,7 +762,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -875,7 +875,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -969,9 +969,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -995,7 +995,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 278f32735..91ecd244d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ members = ["packages/*", "contracts/*"] resolver = "2" [workspace.package] -version = "1.1.2" +version = "2.0.0-rc.0" [workspace.dependencies] cosmwasm-schema = "2.0.0" @@ -20,18 +20,18 @@ semver = "1" serde = { version = "1.0.188", default-features = false, features = ["derive"] } thiserror = "1.0.4" -cw1 = { path = "packages/cw1", version = "1.1.2" } -cw1-whitelist = { path = "contracts/cw1-whitelist", version = "1.1.2", features = [ +cw1 = { path = "packages/cw1", version = "2.0.0-rc.0" } +cw1-whitelist = { path = "contracts/cw1-whitelist", version = "2.0.0-rc.0", features = [ "library", ] } -cw20 = { path = "packages/cw20", version = "1.1.2" } -cw20-base = { path = "contracts/cw20-base", version = "1.1.2", features = ["library"] } -cw3 = { path = "packages/cw3", version = "1.1.2" } -cw3-fixed-multisig = { path = "contracts/cw3-fixed-multisig", version = "1.1.2", features = [ +cw20 = { path = "packages/cw20", version = "2.0.0-rc.0" } +cw20-base = { path = "contracts/cw20-base", version = "2.0.0-rc.0", features = ["library"] } +cw3 = { path = "packages/cw3", version = "2.0.0-rc.0" } +cw3-fixed-multisig = { path = "contracts/cw3-fixed-multisig", version = "2.0.0-rc.0", features = [ "library", ] } -cw4 = { path = "packages/cw4", version = "1.1.2" } -cw4-group = { path = "contracts/cw4-group", version = "1.1.2" } +cw4 = { path = "packages/cw4", version = "2.0.0-rc.0" } +cw4-group = { path = "contracts/cw4-group", version = "2.0.0-rc.0" } easy-addr = { path = "packages/easy-addr" } [profile.release.package.cw1-subkeys] diff --git a/contracts/cw1-subkeys/Cargo.toml b/contracts/cw1-subkeys/Cargo.toml index 06b016464..fae9f4e53 100644 --- a/contracts/cw1-subkeys/Cargo.toml +++ b/contracts/cw1-subkeys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-subkeys" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract" diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 2816ffa51..fec735479 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1-whitelist" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Implementation of an proxy contract using a whitelist" diff --git a/packages/cw1/Cargo.toml b/packages/cw1/Cargo.toml index f9aea5555..645a22dd9 100644 --- a/packages/cw1/Cargo.toml +++ b/packages/cw1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw1" -version = "1.1.2" +version.workspace = true authors = ["Ethan Frey "] edition = "2021" description = "Definition and types for the CosmWasm-1 interface" From 7651543fc4f03c62e8d498f715c8a992ac115553 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 20 Mar 2024 15:20:13 +0100 Subject: [PATCH 622/631] remove obsolete script --- scripts/set_version.sh | 54 ------------------------------------------ 1 file changed, 54 deletions(-) delete mode 100755 scripts/set_version.sh diff --git a/scripts/set_version.sh b/scripts/set_version.sh deleted file mode 100755 index dec6b8483..000000000 --- a/scripts/set_version.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -set -o errexit -o nounset -o pipefail -command -v shellcheck >/dev/null && shellcheck "$0" - -function print_usage() { - echo "Usage: $0 [-h|--help] " - echo "e.g.: $0 0.8.0" -} - -if [ "$#" -ne 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] -then - print_usage - exit 1 -fi - -# Check repo -SCRIPT_DIR="$(realpath "$(dirname "$0")")" -if [[ "$(realpath "$SCRIPT_DIR/..")" != "$(pwd)" ]]; then - echo "Script must be called from the repo root" - exit 2 -fi - -# Ensure repo is not dirty -CHANGES_IN_REPO=$(git status --porcelain --untracked-files=no) -if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 3 -fi - -NEW="$1" -OLD=$(sed -n -e 's/^version[[:space:]]*=[[:space:]]*"\(.*\)"/\1/p' packages/cw20/Cargo.toml) -echo "Updating old version $OLD to new version $NEW ..." - -FILES_MODIFIED=() - -for package_dir in packages/*/; do - CARGO_TOML="$package_dir/Cargo.toml" - sed -i -e "s/version[[:space:]]*=[[:space:]]*\"$OLD\"/version = \"$NEW\"/" "$CARGO_TOML" - FILES_MODIFIED+=("$CARGO_TOML") -done - -for contract_dir in contracts/*/; do - CARGO_TOML="$contract_dir/Cargo.toml" - sed -i -e "s/version[[:space:]]*=[[:space:]]*\"$OLD\"/version = \"$NEW\"/" "$CARGO_TOML" - FILES_MODIFIED+=("$CARGO_TOML") -done - -cargo build -FILES_MODIFIED+=("Cargo.lock") - -echo "Staging ${FILES_MODIFIED[*]} ..." -git add "${FILES_MODIFIED[@]}" -git commit -m "Set version: $NEW" From 0866d9ab8bb3e546a5faf6afebded52f7ed1dc0a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 20 Mar 2024 15:31:10 +0100 Subject: [PATCH 623/631] generate changelog for 2.0.0-rc.0 --- CHANGELOG.md | 1158 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 772 insertions(+), 386 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2df2e2c6..76df00fb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,29 @@ # Changelog -## [1.1.2](https://github.com/CosmWasm/cw-plus/tree/1.1.2) (2023-11-23) +## [v2.0.0-rc.0](https://github.com/CosmWasm/cw-plus/tree/v2.0.0-rc.0) (2024-03-20) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.2...v2.0.0-rc.0) + +**Closed issues:** + +- Error message on Kujira Fin [\#889](https://github.com/CosmWasm/cw-plus/issues/889) + +**Merged pull requests:** + +- Update to `1.5` tooling [\#900](https://github.com/CosmWasm/cw-plus/pull/900) ([uint](https://github.com/uint)) +- Remove CLA and references to non-Apache 2.0 licenses [\#898](https://github.com/CosmWasm/cw-plus/pull/898) ([webmaster128](https://github.com/webmaster128)) +- chore: Move 'controllers' and 'cw2' to 'cw-minus' [\#894](https://github.com/CosmWasm/cw-plus/pull/894) ([kulikthebird](https://github.com/kulikthebird)) +- Update README.md [\#893](https://github.com/CosmWasm/cw-plus/pull/893) ([kmchmk](https://github.com/kmchmk)) +- Fix `Cargo.lock` [\#888](https://github.com/CosmWasm/cw-plus/pull/888) ([chipshort](https://github.com/chipshort)) + +## [v1.1.2](https://github.com/CosmWasm/cw-plus/tree/1.1.2) (2023-11-23) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.1...1.1.2) **Merged pull requests:** -- Add `ensure_from_older_version` [\#886](https://github.com/CosmWasm/cw-plus/pull/886) ([chipshort](https://github.com/chipshort)) +- Add `ensure_from_older_version` [\#886](https://github.com/CosmWasm/cw-plus/pull/886) + ([chipshort](https://github.com/chipshort)) ## [v1.1.1](https://github.com/CosmWasm/cw-plus/tree/v1.1.1) (2023-09-27) @@ -14,15 +31,19 @@ **Closed issues:** -- Issue in providing cw4_stake.wasm contract values for initiating [\#878](https://github.com/CosmWasm/cw-plus/issues/878) +- Issue in providing cw4_stake.wasm contract values for initiating + [\#878](https://github.com/CosmWasm/cw-plus/issues/878) - Bump cw2 version [\#873](https://github.com/CosmWasm/cw-plus/issues/873) **Merged pull requests:** - Update deps [\#882](https://github.com/CosmWasm/cw-plus/pull/882) ([jawoznia](https://github.com/jawoznia)) -- Bumped Rust version and cosmwasm-check version [\#881](https://github.com/CosmWasm/cw-plus/pull/881) ([DariuszDepta](https://github.com/DariuszDepta)) -- Set the resolver version to value 2 [\#880](https://github.com/CosmWasm/cw-plus/pull/880) ([DariuszDepta](https://github.com/DariuszDepta)) -- Upgrade workspace-optimizer to 0.13.0 [\#876](https://github.com/CosmWasm/cw-plus/pull/876) ([webmaster128](https://github.com/webmaster128)) +- Bumped Rust version and cosmwasm-check version [\#881](https://github.com/CosmWasm/cw-plus/pull/881) + ([DariuszDepta](https://github.com/DariuszDepta)) +- Set the resolver version to value 2 [\#880](https://github.com/CosmWasm/cw-plus/pull/880) + ([DariuszDepta](https://github.com/DariuszDepta)) +- Upgrade workspace-optimizer to 0.13.0 [\#876](https://github.com/CosmWasm/cw-plus/pull/876) + ([webmaster128](https://github.com/webmaster128)) ## [v1.1.0](https://github.com/CosmWasm/cw-plus/tree/v1.1.0) (2023-06-19) @@ -32,19 +53,28 @@ - thread 'main' panicked at 'called `Result::unwrap\(\) [\#867](https://github.com/CosmWasm/cw-plus/issues/867) - CW20 All accounts query sorting issue [\#864](https://github.com/CosmWasm/cw-plus/issues/864) -- discussion: cw20-base methods should be nonpayable, or forward funds [\#862](https://github.com/CosmWasm/cw-plus/issues/862) +- discussion: cw20-base methods should be nonpayable, or forward funds + [\#862](https://github.com/CosmWasm/cw-plus/issues/862) - CW2: add a `cw2::VersionError` error type [\#857](https://github.com/CosmWasm/cw-plus/issues/857) **Merged pull requests:** -- Update optimizer to latest [\#870](https://github.com/CosmWasm/cw-plus/pull/870) ([TrevorJTClarke](https://github.com/TrevorJTClarke)) -- Added optional memo to ics20 packets [\#868](https://github.com/CosmWasm/cw-plus/pull/868) ([nicolaslara](https://github.com/nicolaslara)) -- Remove unnecessary zero checks [\#863](https://github.com/CosmWasm/cw-plus/pull/863) ([webmaster128](https://github.com/webmaster128)) -- Update rustc to 1.64 on CI wasm-build [\#861](https://github.com/CosmWasm/cw-plus/pull/861) ([ueco-jb](https://github.com/ueco-jb)) -- Address minor typos in cw1 comments and README [\#860](https://github.com/CosmWasm/cw-plus/pull/860) ([mikedotexe](https://github.com/mikedotexe)) -- Update workspace-optimizer version in README to 0.12.11 [\#859](https://github.com/CosmWasm/cw-plus/pull/859) ([mikedotexe](https://github.com/mikedotexe)) -- CW2: add a method to assert contract version [\#858](https://github.com/CosmWasm/cw-plus/pull/858) ([larry0x](https://github.com/larry0x)) -- Remove non-existent profile [\#856](https://github.com/CosmWasm/cw-plus/pull/856) ([mandrean](https://github.com/mandrean)) +- Update optimizer to latest [\#870](https://github.com/CosmWasm/cw-plus/pull/870) + ([TrevorJTClarke](https://github.com/TrevorJTClarke)) +- Added optional memo to ics20 packets [\#868](https://github.com/CosmWasm/cw-plus/pull/868) + ([nicolaslara](https://github.com/nicolaslara)) +- Remove unnecessary zero checks [\#863](https://github.com/CosmWasm/cw-plus/pull/863) + ([webmaster128](https://github.com/webmaster128)) +- Update rustc to 1.64 on CI wasm-build [\#861](https://github.com/CosmWasm/cw-plus/pull/861) + ([ueco-jb](https://github.com/ueco-jb)) +- Address minor typos in cw1 comments and README [\#860](https://github.com/CosmWasm/cw-plus/pull/860) + ([mikedotexe](https://github.com/mikedotexe)) +- Update workspace-optimizer version in README to 0.12.11 [\#859](https://github.com/CosmWasm/cw-plus/pull/859) + ([mikedotexe](https://github.com/mikedotexe)) +- CW2: add a method to assert contract version [\#858](https://github.com/CosmWasm/cw-plus/pull/858) + ([larry0x](https://github.com/larry0x)) +- Remove non-existent profile [\#856](https://github.com/CosmWasm/cw-plus/pull/856) + ([mandrean](https://github.com/mandrean)) ## [v1.0.1](https://github.com/CosmWasm/cw-plus/tree/v1.0.1) (2022-12-16) @@ -58,7 +88,8 @@ **Merged pull requests:** -- Update dependencies [\#853](https://github.com/CosmWasm/cw-plus/pull/853) ([apollo-sturdy](https://github.com/apollo-sturdy)) +- Update dependencies [\#853](https://github.com/CosmWasm/cw-plus/pull/853) + ([apollo-sturdy](https://github.com/apollo-sturdy)) ## [v1.0.0](https://github.com/CosmWasm/cw-plus/tree/v1.0.0) (2022-11-29) @@ -76,14 +107,17 @@ - Update README [\#832](https://github.com/CosmWasm/cw-plus/issues/832) - Remove `cw1155` and `cw1155-base` [\#830](https://github.com/CosmWasm/cw-plus/issues/830) - Standardize protocol events [\#823](https://github.com/CosmWasm/cw-plus/issues/823) -- Pull out `storage-plus`, `multitest` and `utils` into a separate repo [\#816](https://github.com/CosmWasm/cw-plus/issues/816) +- Pull out `storage-plus`, `multitest` and `utils` into a separate repo + [\#816](https://github.com/CosmWasm/cw-plus/issues/816) - Backport from DAO DAO: optionally charge to make proposal [\#742](https://github.com/CosmWasm/cw-plus/issues/742) - Cannot find Contract address and interface verification [\#679](https://github.com/CosmWasm/cw-plus/issues/679) - Investigate JSON Schema -\> html/md generator [\#573](https://github.com/CosmWasm/cw-plus/issues/573) - Simple framework for gas benchmarking [\#507](https://github.com/CosmWasm/cw-plus/issues/507) - Benchmark "ng" vs. "classic" frameworks [\#505](https://github.com/CosmWasm/cw-plus/issues/505) -- Update reimplemented cw1-whitelist contract, so it uses the custom attribute [\#496](https://github.com/CosmWasm/cw-plus/issues/496) -- Implement attribute macro for trait interface generating boilerplate specific for cw1-whitelist [\#495](https://github.com/CosmWasm/cw-plus/issues/495) +- Update reimplemented cw1-whitelist contract, so it uses the custom attribute + [\#496](https://github.com/CosmWasm/cw-plus/issues/496) +- Implement attribute macro for trait interface generating boilerplate specific for cw1-whitelist + [\#495](https://github.com/CosmWasm/cw-plus/issues/495) - Deriving structural interfaces for contracts [\#493](https://github.com/CosmWasm/cw-plus/issues/493) - Accept &QuerierWrapper not &Querier in helpers [\#390](https://github.com/CosmWasm/cw-plus/issues/390) @@ -91,12 +125,15 @@ - Standardize spec events [\#845](https://github.com/CosmWasm/cw-plus/pull/845) ([uint](https://github.com/uint)) - Add contributing guidelines [\#841](https://github.com/CosmWasm/cw-plus/pull/841) ([uint](https://github.com/uint)) -- Use QuerierWrapper not Querier in cw20 helpers [\#839](https://github.com/CosmWasm/cw-plus/pull/839) ([uint](https://github.com/uint)) +- Use QuerierWrapper not Querier in cw20 helpers [\#839](https://github.com/CosmWasm/cw-plus/pull/839) + ([uint](https://github.com/uint)) - Update CI to Rust 1.64 [\#837](https://github.com/CosmWasm/cw-plus/pull/837) ([uint](https://github.com/uint)) - `README.md` update [\#836](https://github.com/CosmWasm/cw-plus/pull/836) ([uint](https://github.com/uint)) - Remove the AGPL license [\#835](https://github.com/CosmWasm/cw-plus/pull/835) ([uint](https://github.com/uint)) -- Move `utils`, `storage-plus`, `multitest`; remove `cw1155` stuff [\#834](https://github.com/CosmWasm/cw-plus/pull/834) ([uint](https://github.com/uint)) -- Add an optional proposal deposit to cw3-flex-multisig [\#751](https://github.com/CosmWasm/cw-plus/pull/751) ([0xekez](https://github.com/0xekez)) +- Move `utils`, `storage-plus`, `multitest`; remove `cw1155` stuff [\#834](https://github.com/CosmWasm/cw-plus/pull/834) + ([uint](https://github.com/uint)) +- Add an optional proposal deposit to cw3-flex-multisig [\#751](https://github.com/CosmWasm/cw-plus/pull/751) + ([0xekez](https://github.com/0xekez)) ## [v0.16.0](https://github.com/CosmWasm/cw-plus/tree/v0.16.0) (2022-10-14) @@ -105,27 +142,35 @@ **Closed issues:** - Unable to run workspace-optimizer [\#828](https://github.com/CosmWasm/cw-plus/issues/828) -- Running the build command for the production-ready build for cw-20 and not only ends an error [\#821](https://github.com/CosmWasm/cw-plus/issues/821) +- Running the build command for the production-ready build for cw-20 and not only ends an error + [\#821](https://github.com/CosmWasm/cw-plus/issues/821) - Fill out missing high-level docs [\#806](https://github.com/CosmWasm/cw-plus/issues/806) -- Some multitest bindings for staking are missing such as `BondedDenom` [\#753](https://github.com/CosmWasm/cw-plus/issues/753) +- Some multitest bindings for staking are missing such as `BondedDenom` + [\#753](https://github.com/CosmWasm/cw-plus/issues/753) - Allow burn to have a callback just like Send [\#717](https://github.com/CosmWasm/cw-plus/issues/717) -- Unable to upload cw20\_base wasm file on terra-station [\#716](https://github.com/CosmWasm/cw-plus/issues/716) +- Unable to upload cw20_base wasm file on terra-station [\#716](https://github.com/CosmWasm/cw-plus/issues/716) - Cannot upload to localterra with cw-storage-plus 0.12.1 [\#666](https://github.com/CosmWasm/cw-plus/issues/666) - Is `MAX_LIMIT` a bug? [\#625](https://github.com/CosmWasm/cw-plus/issues/625) - Add support for admin migrations to cw-multitest [\#744](https://github.com/CosmWasm/cw-plus/issues/744) **Merged pull requests:** -- Remove `cosmwasm-storage` dependency [\#827](https://github.com/CosmWasm/cw-plus/pull/827) ([uint](https://github.com/uint)) -- Generic query for cw3 unification [\#826](https://github.com/CosmWasm/cw-plus/pull/826) ([hashedone](https://github.com/hashedone)) +- Remove `cosmwasm-storage` dependency [\#827](https://github.com/CosmWasm/cw-plus/pull/827) + ([uint](https://github.com/uint)) +- Generic query for cw3 unification [\#826](https://github.com/CosmWasm/cw-plus/pull/826) + ([hashedone](https://github.com/hashedone)) - Remove cw1-whitelist-ng [\#825](https://github.com/CosmWasm/cw-plus/pull/825) ([uint](https://github.com/uint)) - Deque changes [\#822](https://github.com/CosmWasm/cw-plus/pull/822) ([chipshort](https://github.com/chipshort)) - Add missing docs [\#818](https://github.com/CosmWasm/cw-plus/pull/818) ([chipshort](https://github.com/chipshort)) -- Remove storage-plus dependency from storage-macro [\#817](https://github.com/CosmWasm/cw-plus/pull/817) ([chipshort](https://github.com/chipshort)) -- \[multi-test\] Add update and clear admin support to WasmKeeper [\#812](https://github.com/CosmWasm/cw-plus/pull/812) ([chipshort](https://github.com/chipshort)) +- Remove storage-plus dependency from storage-macro [\#817](https://github.com/CosmWasm/cw-plus/pull/817) + ([chipshort](https://github.com/chipshort)) +- \[multi-test\] Add update and clear admin support to WasmKeeper [\#812](https://github.com/CosmWasm/cw-plus/pull/812) + ([chipshort](https://github.com/chipshort)) - Update CHANGELOG [\#811](https://github.com/CosmWasm/cw-plus/pull/811) ([uint](https://github.com/uint)) -- \[multi-test\] Add staking and distribution module [\#782](https://github.com/CosmWasm/cw-plus/pull/782) ([ueco-jb](https://github.com/ueco-jb)) -- Handle duplicate members in cw4-group create [\#702](https://github.com/CosmWasm/cw-plus/pull/702) ([codehans](https://github.com/codehans)) +- \[multi-test\] Add staking and distribution module [\#782](https://github.com/CosmWasm/cw-plus/pull/782) + ([ueco-jb](https://github.com/ueco-jb)) +- Handle duplicate members in cw4-group create [\#702](https://github.com/CosmWasm/cw-plus/pull/702) + ([codehans](https://github.com/codehans)) ## [v0.15.1](https://github.com/CosmWasm/cw-plus/tree/v0.15.1) (2022-09-27) @@ -139,9 +184,12 @@ - Release 0.15.1 [\#809](https://github.com/CosmWasm/cw-plus/pull/809) ([uint](https://github.com/uint)) - Add Deque [\#807](https://github.com/CosmWasm/cw-plus/pull/807) ([chipshort](https://github.com/chipshort)) -- Cw1155-base public queries and move tests [\#804](https://github.com/CosmWasm/cw-plus/pull/804) ([ismellike](https://github.com/ismellike)) -- Add clear and is\_empty methods to Map [\#803](https://github.com/CosmWasm/cw-plus/pull/803) ([manu0466](https://github.com/manu0466)) -- SnapshotItem total, public query methods, and safe math [\#802](https://github.com/CosmWasm/cw-plus/pull/802) ([ismellike](https://github.com/ismellike)) +- Cw1155-base public queries and move tests [\#804](https://github.com/CosmWasm/cw-plus/pull/804) + ([ismellike](https://github.com/ismellike)) +- Add clear and is_empty methods to Map [\#803](https://github.com/CosmWasm/cw-plus/pull/803) + ([manu0466](https://github.com/manu0466)) +- SnapshotItem total, public query methods, and safe math [\#802](https://github.com/CosmWasm/cw-plus/pull/802) + ([ismellike](https://github.com/ismellike)) ## [v0.15.0](https://github.com/CosmWasm/cw-plus/tree/v0.15.0) (2022-09-14) @@ -158,41 +206,59 @@ **Closed issues:** -- Adapt build\_and\_upload\_schemas CI job to new schema format [\#795](https://github.com/CosmWasm/cw-plus/issues/795) +- Adapt build_and_upload_schemas CI job to new schema format [\#795](https://github.com/CosmWasm/cw-plus/issues/795) - Remove `IntKeyOld` [\#775](https://github.com/CosmWasm/cw-plus/issues/775) -- Can I cover all tests with cw\_multi\_test? [\#771](https://github.com/CosmWasm/cw-plus/issues/771) +- Can I cover all tests with cw_multi_test? [\#771](https://github.com/CosmWasm/cw-plus/issues/771) - Make cw1155 can add token's url at the first mint [\#764](https://github.com/CosmWasm/cw-plus/issues/764) - Expose `Response` from contract in cw-multi-test execute [\#763](https://github.com/CosmWasm/cw-plus/issues/763) -- Restructure `Index` trait to allow for more extensive `Index` struct implementation. [\#757](https://github.com/CosmWasm/cw-plus/issues/757) -- Consider moving schema boilerplate from `examples` to a binary crate [\#755](https://github.com/CosmWasm/cw-plus/issues/755) +- Restructure `Index` trait to allow for more extensive `Index` struct implementation. + [\#757](https://github.com/CosmWasm/cw-plus/issues/757) +- Consider moving schema boilerplate from `examples` to a binary crate + [\#755](https://github.com/CosmWasm/cw-plus/issues/755) - Wrong/unclear explanation in IndexedMap docs [\#718](https://github.com/CosmWasm/cw-plus/issues/718) - Redundant logic in `ThresholdResponse` multisigs [\#677](https://github.com/CosmWasm/cw-plus/issues/677) - \[cw3-flex/fixed-multisig\] Reject proposals early [\#665](https://github.com/CosmWasm/cw-plus/issues/665) -- cw20 allowance expiration can be set to a block height or timestamp in the past [\#628](https://github.com/CosmWasm/cw-plus/issues/628) +- cw20 allowance expiration can be set to a block height or timestamp in the past + [\#628](https://github.com/CosmWasm/cw-plus/issues/628) - Add security policy [\#580](https://github.com/CosmWasm/cw-plus/issues/580) - Update MIGRATING.md doc for multi test [\#490](https://github.com/CosmWasm/cw-plus/issues/490) **Merged pull requests:** -- CI: unified .json schema artifacts for contracts [\#798](https://github.com/CosmWasm/cw-plus/pull/798) ([uint](https://github.com/uint)) -- cw4 contracts: clean up imports and reexports [\#797](https://github.com/CosmWasm/cw-plus/pull/797) ([uint](https://github.com/uint)) +- CI: unified .json schema artifacts for contracts [\#798](https://github.com/CosmWasm/cw-plus/pull/798) + ([uint](https://github.com/uint)) +- cw4 contracts: clean up imports and reexports [\#797](https://github.com/CosmWasm/cw-plus/pull/797) + ([uint](https://github.com/uint)) - Fix `cargo wasm` [\#794](https://github.com/CosmWasm/cw-plus/pull/794) ([uint](https://github.com/uint)) -- Validate allowance expiration [\#793](https://github.com/CosmWasm/cw-plus/pull/793) ([chipshort](https://github.com/chipshort)) +- Validate allowance expiration [\#793](https://github.com/CosmWasm/cw-plus/pull/793) + ([chipshort](https://github.com/chipshort)) - Update to CosmWasm 1.1.0 [\#791](https://github.com/CosmWasm/cw-plus/pull/791) ([uint](https://github.com/uint)) - CosmWasm `1.1.0-rc.1` [\#789](https://github.com/CosmWasm/cw-plus/pull/789) ([uint](https://github.com/uint)) -- Updating broken link to cw3-flex-multisig [\#787](https://github.com/CosmWasm/cw-plus/pull/787) ([0xriku](https://github.com/0xriku)) -- Multisig status logic follow-up [\#784](https://github.com/CosmWasm/cw-plus/pull/784) ([maurolacy](https://github.com/maurolacy)) -- Multisig status logic [\#783](https://github.com/CosmWasm/cw-plus/pull/783) ([maurolacy](https://github.com/maurolacy)) -- Add primary key to `MultiIndex` index fn params [\#781](https://github.com/CosmWasm/cw-plus/pull/781) ([maurolacy](https://github.com/maurolacy)) +- Updating broken link to cw3-flex-multisig [\#787](https://github.com/CosmWasm/cw-plus/pull/787) + ([0xriku](https://github.com/0xriku)) +- Multisig status logic follow-up [\#784](https://github.com/CosmWasm/cw-plus/pull/784) + ([maurolacy](https://github.com/maurolacy)) +- Multisig status logic [\#783](https://github.com/CosmWasm/cw-plus/pull/783) + ([maurolacy](https://github.com/maurolacy)) +- Add primary key to `MultiIndex` index fn params [\#781](https://github.com/CosmWasm/cw-plus/pull/781) + ([maurolacy](https://github.com/maurolacy)) - Fix typo [\#779](https://github.com/CosmWasm/cw-plus/pull/779) ([LeTurt333](https://github.com/LeTurt333)) -- Remove deprecated `IntKeyOld` [\#778](https://github.com/CosmWasm/cw-plus/pull/778) ([ueco-jb](https://github.com/ueco-jb)) -- Small fixes / updates to storage-plus docs [\#777](https://github.com/CosmWasm/cw-plus/pull/777) ([maurolacy](https://github.com/maurolacy)) -- Fix: `Prefix::keys` return errors [\#774](https://github.com/CosmWasm/cw-plus/pull/774) ([maurolacy](https://github.com/maurolacy)) -- Expose cw-multi-test `FailingModule` [\#773](https://github.com/CosmWasm/cw-plus/pull/773) ([dadamu](https://github.com/dadamu)) -- Style: move `InstantiateMsg` validation in impl [\#772](https://github.com/CosmWasm/cw-plus/pull/772) ([etienne-napoleone](https://github.com/etienne-napoleone)) -- Make ExecuteEnv fields public [\#770](https://github.com/CosmWasm/cw-plus/pull/770) ([ismellike](https://github.com/ismellike)) -- Change / fix packages publishing order [\#769](https://github.com/CosmWasm/cw-plus/pull/769) ([maurolacy](https://github.com/maurolacy)) -- contracts: move schema gen boilerplate to a binary crate [\#760](https://github.com/CosmWasm/cw-plus/pull/760) ([uint](https://github.com/uint)) +- Remove deprecated `IntKeyOld` [\#778](https://github.com/CosmWasm/cw-plus/pull/778) + ([ueco-jb](https://github.com/ueco-jb)) +- Small fixes / updates to storage-plus docs [\#777](https://github.com/CosmWasm/cw-plus/pull/777) + ([maurolacy](https://github.com/maurolacy)) +- Fix: `Prefix::keys` return errors [\#774](https://github.com/CosmWasm/cw-plus/pull/774) + ([maurolacy](https://github.com/maurolacy)) +- Expose cw-multi-test `FailingModule` [\#773](https://github.com/CosmWasm/cw-plus/pull/773) + ([dadamu](https://github.com/dadamu)) +- Style: move `InstantiateMsg` validation in impl [\#772](https://github.com/CosmWasm/cw-plus/pull/772) + ([etienne-napoleone](https://github.com/etienne-napoleone)) +- Make ExecuteEnv fields public [\#770](https://github.com/CosmWasm/cw-plus/pull/770) + ([ismellike](https://github.com/ismellike)) +- Change / fix packages publishing order [\#769](https://github.com/CosmWasm/cw-plus/pull/769) + ([maurolacy](https://github.com/maurolacy)) +- contracts: move schema gen boilerplate to a binary crate [\#760](https://github.com/CosmWasm/cw-plus/pull/760) + ([uint](https://github.com/uint)) ## [v0.14.0](https://github.com/CosmWasm/cw-plus/tree/v0.14.0) (2022-07-27) @@ -204,28 +270,45 @@ - Allow querying all granted allowances to a spender [\#756](https://github.com/CosmWasm/cw-plus/issues/756) - Store compiled wasms on repo [\#747](https://github.com/CosmWasm/cw-plus/issues/747) - Add optional executor restriction to cw3-flex [\#739](https://github.com/CosmWasm/cw-plus/issues/739) -- Provide proc macro package for automatic `IndexList` implementation on any index struct [\#736](https://github.com/CosmWasm/cw-plus/issues/736) -- MultiIndex `prefix` and `sub_prefix` working incorrectly when using a triple element tuple as IK [\#730](https://github.com/CosmWasm/cw-plus/issues/730) +- Provide proc macro package for automatic `IndexList` implementation on any index struct + [\#736](https://github.com/CosmWasm/cw-plus/issues/736) +- MultiIndex `prefix` and `sub_prefix` working incorrectly when using a triple element tuple as IK + [\#730](https://github.com/CosmWasm/cw-plus/issues/730) - Errors when compiling all the contracts [\#724](https://github.com/CosmWasm/cw-plus/issues/724) - Test-specific helpers in storage-plus [\#708](https://github.com/CosmWasm/cw-plus/issues/708) **Merged pull requests:** -- Updated contract versions and links [\#762](https://github.com/CosmWasm/cw-plus/pull/762) ([daniel-farina](https://github.com/daniel-farina)) -- Allowances per spender [\#761](https://github.com/CosmWasm/cw-plus/pull/761) ([maurolacy](https://github.com/maurolacy)) -- Fix broken links, minor typo [\#752](https://github.com/CosmWasm/cw-plus/pull/752) ([mikedotexe](https://github.com/mikedotexe)) -- Use into\_iter\(\) instead of iter\(\).cloned\(\). [\#749](https://github.com/CosmWasm/cw-plus/pull/749) ([ezekiiel](https://github.com/ezekiiel)) -- Add ability to unset minter in UpdateMinter message. [\#748](https://github.com/CosmWasm/cw-plus/pull/748) ([ezekiiel](https://github.com/ezekiiel)) -- Fix specification about CW20 Enumerable Queries [\#746](https://github.com/CosmWasm/cw-plus/pull/746) ([lukepark327](https://github.com/lukepark327)) -- Add migrate method to cw20 base. [\#745](https://github.com/CosmWasm/cw-plus/pull/745) ([ezekiiel](https://github.com/ezekiiel)) -- Add optional executor restriction to cw3-flex [\#741](https://github.com/CosmWasm/cw-plus/pull/741) ([ueco-jb](https://github.com/ueco-jb)) -- Add proc macro package for automatic `IndexList` implementation [\#737](https://github.com/CosmWasm/cw-plus/pull/737) ([y-pakorn](https://github.com/y-pakorn)) -- Bump workspace-optimizer version in README to `0.12.6` [\#735](https://github.com/CosmWasm/cw-plus/pull/735) ([uint](https://github.com/uint)) -- Use standard CosmosMsg [\#734](https://github.com/CosmWasm/cw-plus/pull/734) ([ethanfrey](https://github.com/ethanfrey)) -- add execute msg to update minter [\#729](https://github.com/CosmWasm/cw-plus/pull/729) ([janitachalam](https://github.com/janitachalam)) -- Removed documentation from Cargo.toml [\#711](https://github.com/CosmWasm/cw-plus/pull/711) ([hashedone](https://github.com/hashedone)) -- Move test helpers into a test section [\#709](https://github.com/CosmWasm/cw-plus/pull/709) ([shanev](https://github.com/shanev)) -- add query\_this\_hook to hooks.rs [\#688](https://github.com/CosmWasm/cw-plus/pull/688) ([ishaanh](https://github.com/ishaanh)) +- Updated contract versions and links [\#762](https://github.com/CosmWasm/cw-plus/pull/762) + ([daniel-farina](https://github.com/daniel-farina)) +- Allowances per spender [\#761](https://github.com/CosmWasm/cw-plus/pull/761) + ([maurolacy](https://github.com/maurolacy)) +- Fix broken links, minor typo [\#752](https://github.com/CosmWasm/cw-plus/pull/752) + ([mikedotexe](https://github.com/mikedotexe)) +- Use into_iter\(\) instead of iter\(\).cloned\(\). [\#749](https://github.com/CosmWasm/cw-plus/pull/749) + ([ezekiiel](https://github.com/ezekiiel)) +- Add ability to unset minter in UpdateMinter message. [\#748](https://github.com/CosmWasm/cw-plus/pull/748) + ([ezekiiel](https://github.com/ezekiiel)) +- Fix specification about CW20 Enumerable Queries [\#746](https://github.com/CosmWasm/cw-plus/pull/746) + ([lukepark327](https://github.com/lukepark327)) +- Add migrate method to cw20 base. [\#745](https://github.com/CosmWasm/cw-plus/pull/745) + ([ezekiiel](https://github.com/ezekiiel)) +- Add optional executor restriction to cw3-flex [\#741](https://github.com/CosmWasm/cw-plus/pull/741) + ([ueco-jb](https://github.com/ueco-jb)) +- Add proc macro package for automatic `IndexList` implementation + [\#737](https://github.com/CosmWasm/cw-plus/pull/737) ([y-pakorn](https://github.com/y-pakorn)) +- Bump workspace-optimizer version in README to `0.12.6` [\#735](https://github.com/CosmWasm/cw-plus/pull/735) + ([uint](https://github.com/uint)) +- Use standard CosmosMsg [\#734](https://github.com/CosmWasm/cw-plus/pull/734) + ([ethanfrey](https://github.com/ethanfrey)) +- add execute msg to update minter [\#729](https://github.com/CosmWasm/cw-plus/pull/729) + ([janitachalam](https://github.com/janitachalam)) +- Removed documentation from Cargo.toml [\#711](https://github.com/CosmWasm/cw-plus/pull/711) + ([hashedone](https://github.com/hashedone)) +- Move test helpers into a test section [\#709](https://github.com/CosmWasm/cw-plus/pull/709) + ([shanev](https://github.com/shanev)) +- add query_this_hook to hooks.rs [\#688](https://github.com/CosmWasm/cw-plus/pull/688) + ([ishaanh](https://github.com/ishaanh)) ## [v0.13.4](https://github.com/CosmWasm/cw-plus/tree/v0.13.4) (2022-06-02) @@ -246,14 +329,18 @@ **Merged pull requests:** - Repo reclippization [\#721](https://github.com/CosmWasm/cw-plus/pull/721) ([hashedone](https://github.com/hashedone)) -- Add code coverage to CI [\#715](https://github.com/CosmWasm/cw-plus/pull/715) ([maurolacy](https://github.com/maurolacy)) +- Add code coverage to CI [\#715](https://github.com/CosmWasm/cw-plus/pull/715) + ([maurolacy](https://github.com/maurolacy)) - Update item.rs: typo [\#713](https://github.com/CosmWasm/cw-plus/pull/713) ([rtviii](https://github.com/rtviii)) -- Update link to new shared CosmWasm SECURITY.md [\#701](https://github.com/CosmWasm/cw-plus/pull/701) ([webmaster128](https://github.com/webmaster128)) -- Add existence checking to indexed map [\#700](https://github.com/CosmWasm/cw-plus/pull/700) ([shanev](https://github.com/shanev)) +- Update link to new shared CosmWasm SECURITY.md [\#701](https://github.com/CosmWasm/cw-plus/pull/701) + ([webmaster128](https://github.com/webmaster128)) +- Add existence checking to indexed map [\#700](https://github.com/CosmWasm/cw-plus/pull/700) + ([shanev](https://github.com/shanev)) **Closed issues:** -- error: could not compile `ff` when running cargo test on cw20-base contract [\#714](https://github.com/CosmWasm/cw-plus/issues/714) +- error: could not compile `ff` when running cargo test on cw20-base contract + [\#714](https://github.com/CosmWasm/cw-plus/issues/714) ## [v0.13.2](https://github.com/CosmWasm/cw-plus/tree/v0.13.2) (2022-04-11) @@ -261,19 +348,26 @@ **Closed issues:** -- `KeyDeserialize` trait is private making custom keys and generics over keys not possible. [\#691](https://github.com/CosmWasm/cw-plus/issues/691) -- unresolved import cosmwasm\_std::testing [\#681](https://github.com/CosmWasm/cw-plus/issues/681) +- `KeyDeserialize` trait is private making custom keys and generics over keys not possible. + [\#691](https://github.com/CosmWasm/cw-plus/issues/691) +- unresolved import cosmwasm_std::testing [\#681](https://github.com/CosmWasm/cw-plus/issues/681) - Add non-owned `range_de` [\#463](https://github.com/CosmWasm/cw-plus/issues/463) **Merged pull requests:** -- Upgrade all contracts and packages to cosmwasm-std beta8 [\#699](https://github.com/CosmWasm/cw-plus/pull/699) ([the-frey](https://github.com/the-frey)) +- Upgrade all contracts and packages to cosmwasm-std beta8 [\#699](https://github.com/CosmWasm/cw-plus/pull/699) + ([the-frey](https://github.com/the-frey)) - Remove dead links [\#698](https://github.com/CosmWasm/cw-plus/pull/698) ([Psyf](https://github.com/Psyf)) -- cw20-ics20: fix missing assert [\#697](https://github.com/CosmWasm/cw-plus/pull/697) ([giansalex](https://github.com/giansalex)) -- storage-plus: Implement u128 key [\#694](https://github.com/CosmWasm/cw-plus/pull/694) ([orkunkl](https://github.com/orkunkl)) -- Make `KeyDeserialize` trait public [\#692](https://github.com/CosmWasm/cw-plus/pull/692) ([maurolacy](https://github.com/maurolacy)) -- Typo in QueryMsg::DownloadLogo description [\#690](https://github.com/CosmWasm/cw-plus/pull/690) ([nnoln](https://github.com/nnoln)) -- Fix publish.sh help / args [\#689](https://github.com/CosmWasm/cw-plus/pull/689) ([maurolacy](https://github.com/maurolacy)) +- cw20-ics20: fix missing assert [\#697](https://github.com/CosmWasm/cw-plus/pull/697) + ([giansalex](https://github.com/giansalex)) +- storage-plus: Implement u128 key [\#694](https://github.com/CosmWasm/cw-plus/pull/694) + ([orkunkl](https://github.com/orkunkl)) +- Make `KeyDeserialize` trait public [\#692](https://github.com/CosmWasm/cw-plus/pull/692) + ([maurolacy](https://github.com/maurolacy)) +- Typo in QueryMsg::DownloadLogo description [\#690](https://github.com/CosmWasm/cw-plus/pull/690) + ([nnoln](https://github.com/nnoln)) +- Fix publish.sh help / args [\#689](https://github.com/CosmWasm/cw-plus/pull/689) + ([maurolacy](https://github.com/maurolacy)) ## [v0.13.1](https://github.com/CosmWasm/cw-plus/tree/v0.13.1) (2022-03-25) @@ -284,17 +378,24 @@ - cw20-base: duplicate accounts get overwritten in Init [\#683](https://github.com/CosmWasm/cw-plus/issues/683) - Implementation of hooks.rs \(not\) as `HashMap` [\#682](https://github.com/CosmWasm/cw-plus/issues/682) - ICS20, invalid packet data [\#662](https://github.com/CosmWasm/cw-plus/issues/662) -- Duplicate accounts in cw20 initial balances causes unrecoverable inconsistent state [\#626](https://github.com/CosmWasm/cw-plus/issues/626) +- Duplicate accounts in cw20 initial balances causes unrecoverable inconsistent state + [\#626](https://github.com/CosmWasm/cw-plus/issues/626) **Merged pull requests:** -- Add default gas limit to cw20-ics20 [\#685](https://github.com/CosmWasm/cw-plus/pull/685) ([ethanfrey](https://github.com/ethanfrey)) -- Fix cw20 ics20 packets [\#684](https://github.com/CosmWasm/cw-plus/pull/684) ([ethanfrey](https://github.com/ethanfrey)) -- Clarify the stability of cw-storage-plus, no longer Experimental [\#676](https://github.com/CosmWasm/cw-plus/pull/676) ([ethanfrey](https://github.com/ethanfrey)) -- Update changelog add upcoming [\#675](https://github.com/CosmWasm/cw-plus/pull/675) ([maurolacy](https://github.com/maurolacy)) +- Add default gas limit to cw20-ics20 [\#685](https://github.com/CosmWasm/cw-plus/pull/685) + ([ethanfrey](https://github.com/ethanfrey)) +- Fix cw20 ics20 packets [\#684](https://github.com/CosmWasm/cw-plus/pull/684) + ([ethanfrey](https://github.com/ethanfrey)) +- Clarify the stability of cw-storage-plus, no longer Experimental [\#676](https://github.com/CosmWasm/cw-plus/pull/676) + ([ethanfrey](https://github.com/ethanfrey)) +- Update changelog add upcoming [\#675](https://github.com/CosmWasm/cw-plus/pull/675) + ([maurolacy](https://github.com/maurolacy)) - Reject proposals early [\#668](https://github.com/CosmWasm/cw-plus/pull/668) ([Callum-A](https://github.com/Callum-A)) -- cw20-base: validate addresses are unique in initial balances [\#659](https://github.com/CosmWasm/cw-plus/pull/659) ([harryscholes](https://github.com/harryscholes)) -- New SECURITY.md refering to wasmd [\#624](https://github.com/CosmWasm/cw-plus/pull/624) ([ethanfrey](https://github.com/ethanfrey)) +- cw20-base: validate addresses are unique in initial balances [\#659](https://github.com/CosmWasm/cw-plus/pull/659) + ([harryscholes](https://github.com/harryscholes)) +- New SECURITY.md refering to wasmd [\#624](https://github.com/CosmWasm/cw-plus/pull/624) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.13.0](https://github.com/CosmWasm/cw-plus/tree/v0.13.0) (2022-03-09) @@ -308,15 +409,21 @@ - Release `cw-plus` v0.13.0 [\#673](https://github.com/CosmWasm/cw-plus/issues/673) - Querying over composite key [\#664](https://github.com/CosmWasm/cw-plus/issues/664) -- the method `may_load` exists for struct `cw_storage_plus::Map<'static, (std::string::String, Uint256), Uint256>`, but its trait bounds were not satisfied the following trait bounds were not satisfied: `(std::string::String, Uint256): PrimaryKey` [\#663](https://github.com/CosmWasm/cw-plus/issues/663) +- the method `may_load` exists for struct `cw_storage_plus::Map<'static, (std::string::String, Uint256), Uint256>`, but + its trait bounds were not satisfied the following trait bounds were not satisfied: + `(std::string::String, Uint256): PrimaryKey` [\#663](https://github.com/CosmWasm/cw-plus/issues/663) - Make `Bound` helpers return `Option` [\#644](https://github.com/CosmWasm/cw-plus/issues/644) **Merged pull requests:** -- Update cosmwasm to 1.0.0-beta6 [\#672](https://github.com/CosmWasm/cw-plus/pull/672) ([webmaster128](https://github.com/webmaster128)) -- Update storage plus docs / Remove `MultiIndex` PK default [\#671](https://github.com/CosmWasm/cw-plus/pull/671) ([maurolacy](https://github.com/maurolacy)) -- fix: Remove old TODO comment in cw3-flex readme [\#661](https://github.com/CosmWasm/cw-plus/pull/661) ([apollo-sturdy](https://github.com/apollo-sturdy)) -- Properly handle generic queries in multi-test [\#660](https://github.com/CosmWasm/cw-plus/pull/660) ([ethanfrey](https://github.com/ethanfrey)) +- Update cosmwasm to 1.0.0-beta6 [\#672](https://github.com/CosmWasm/cw-plus/pull/672) + ([webmaster128](https://github.com/webmaster128)) +- Update storage plus docs / Remove `MultiIndex` PK default [\#671](https://github.com/CosmWasm/cw-plus/pull/671) + ([maurolacy](https://github.com/maurolacy)) +- fix: Remove old TODO comment in cw3-flex readme [\#661](https://github.com/CosmWasm/cw-plus/pull/661) + ([apollo-sturdy](https://github.com/apollo-sturdy)) +- Properly handle generic queries in multi-test [\#660](https://github.com/CosmWasm/cw-plus/pull/660) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.12.1](https://github.com/CosmWasm/cw-plus/tree/v0.12.1) (2022-02-14) @@ -324,9 +431,12 @@ **Merged pull requests:** -- Fix missing custom query [\#657](https://github.com/CosmWasm/cw-plus/pull/657) ([maurolacy](https://github.com/maurolacy)) -- Forward original errors in multitest `instantiate`, `execute` and `query` [\#656](https://github.com/CosmWasm/cw-plus/pull/656) ([maurolacy](https://github.com/maurolacy)) -- Fix missing prefix bound types [\#655](https://github.com/CosmWasm/cw-plus/pull/655) ([maurolacy](https://github.com/maurolacy)) +- Fix missing custom query [\#657](https://github.com/CosmWasm/cw-plus/pull/657) + ([maurolacy](https://github.com/maurolacy)) +- Forward original errors in multitest `instantiate`, `execute` and `query` + [\#656](https://github.com/CosmWasm/cw-plus/pull/656) ([maurolacy](https://github.com/maurolacy)) +- Fix missing prefix bound types [\#655](https://github.com/CosmWasm/cw-plus/pull/655) + ([maurolacy](https://github.com/maurolacy)) ## [v0.12.0](https://github.com/CosmWasm/cw-plus/tree/v0.12.0) (2022-02-09) @@ -345,8 +455,9 @@ - Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) - Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) - Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) -- Incorrect Cw4ExecuteMsg used during remove\_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) -- \[cw3-flex/fixed-multisig\] Status changes after voting and proposal expiration [\#630](https://github.com/CosmWasm/cw-plus/issues/630) +- Incorrect Cw4ExecuteMsg used during remove_hook [\#637](https://github.com/CosmWasm/cw-plus/issues/637) +- \[cw3-flex/fixed-multisig\] Status changes after voting and proposal expiration + [\#630](https://github.com/CosmWasm/cw-plus/issues/630) - Make `Bound`s type safe [\#462](https://github.com/CosmWasm/cw-plus/issues/462) - Move all cw20 examples to new repo [\#578](https://github.com/CosmWasm/cw-plus/issues/578) - Add more debug output from multi-test [\#575](https://github.com/CosmWasm/cw-plus/issues/575) @@ -354,31 +465,54 @@ **Merged pull requests:** - Prepare release v0.12.0 [\#654](https://github.com/CosmWasm/cw-plus/pull/654) ([uint](https://github.com/uint)) -- Ics20 same ack handling as ibctransfer [\#653](https://github.com/CosmWasm/cw-plus/pull/653) ([ethanfrey](https://github.com/ethanfrey)) -- packages: support custom queries [\#652](https://github.com/CosmWasm/cw-plus/pull/652) ([uint](https://github.com/uint)) -- CW20 - Fix Docs URL [\#649](https://github.com/CosmWasm/cw-plus/pull/649) ([entrancedjames](https://github.com/entrancedjames)) -- CW3: Add proposal\_id field to VoteInfo structure [\#648](https://github.com/CosmWasm/cw-plus/pull/648) ([ueco-jb](https://github.com/ueco-jb)) -- Use ContractInfoResponse from cosmwasm\_std [\#646](https://github.com/CosmWasm/cw-plus/pull/646) ([webmaster128](https://github.com/webmaster128)) -- Fix status/execution bugs in flex-multisig [\#643](https://github.com/CosmWasm/cw-plus/pull/643) ([uint](https://github.com/uint)) -- Set version: 0.12.0-alpha2 [\#642](https://github.com/CosmWasm/cw-plus/pull/642) ([ethanfrey](https://github.com/ethanfrey)) -- Allow modifying admin of Ics20 contract [\#641](https://github.com/CosmWasm/cw-plus/pull/641) ([ethanfrey](https://github.com/ethanfrey)) -- `MIGRATING.md` update / examples for type safe bounds [\#640](https://github.com/CosmWasm/cw-plus/pull/640) ([maurolacy](https://github.com/maurolacy)) -- Fix benchmarks \(after 1.58.1 update\) [\#639](https://github.com/CosmWasm/cw-plus/pull/639) ([maurolacy](https://github.com/maurolacy)) -- Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) ([maurolacy](https://github.com/maurolacy)) +- Ics20 same ack handling as ibctransfer [\#653](https://github.com/CosmWasm/cw-plus/pull/653) + ([ethanfrey](https://github.com/ethanfrey)) +- packages: support custom queries [\#652](https://github.com/CosmWasm/cw-plus/pull/652) + ([uint](https://github.com/uint)) +- CW20 - Fix Docs URL [\#649](https://github.com/CosmWasm/cw-plus/pull/649) + ([entrancedjames](https://github.com/entrancedjames)) +- CW3: Add proposal_id field to VoteInfo structure [\#648](https://github.com/CosmWasm/cw-plus/pull/648) + ([ueco-jb](https://github.com/ueco-jb)) +- Use ContractInfoResponse from cosmwasm_std [\#646](https://github.com/CosmWasm/cw-plus/pull/646) + ([webmaster128](https://github.com/webmaster128)) +- Fix status/execution bugs in flex-multisig [\#643](https://github.com/CosmWasm/cw-plus/pull/643) + ([uint](https://github.com/uint)) +- Set version: 0.12.0-alpha2 [\#642](https://github.com/CosmWasm/cw-plus/pull/642) + ([ethanfrey](https://github.com/ethanfrey)) +- Allow modifying admin of Ics20 contract [\#641](https://github.com/CosmWasm/cw-plus/pull/641) + ([ethanfrey](https://github.com/ethanfrey)) +- `MIGRATING.md` update / examples for type safe bounds [\#640](https://github.com/CosmWasm/cw-plus/pull/640) + ([maurolacy](https://github.com/maurolacy)) +- Fix benchmarks \(after 1.58.1 update\) [\#639](https://github.com/CosmWasm/cw-plus/pull/639) + ([maurolacy](https://github.com/maurolacy)) +- Fix `remove_hook` helper [\#638](https://github.com/CosmWasm/cw-plus/pull/638) + ([maurolacy](https://github.com/maurolacy)) - Type safe bounds [\#627](https://github.com/CosmWasm/cw-plus/pull/627) ([maurolacy](https://github.com/maurolacy)) -- Update Rust to v1.54.0 in CI [\#636](https://github.com/CosmWasm/cw-plus/pull/636) ([maurolacy](https://github.com/maurolacy)) +- Update Rust to v1.54.0 in CI [\#636](https://github.com/CosmWasm/cw-plus/pull/636) + ([maurolacy](https://github.com/maurolacy)) - Refactor cw2 spec readme [\#635](https://github.com/CosmWasm/cw-plus/pull/635) ([orkunkl](https://github.com/orkunkl)) -- Fix tag consolidation for matching CHANGELOG entries [\#634](https://github.com/CosmWasm/cw-plus/pull/634) ([maurolacy](https://github.com/maurolacy)) -- Ics20 contract rollback [\#633](https://github.com/CosmWasm/cw-plus/pull/633) ([ethanfrey](https://github.com/ethanfrey)) -- Fix typo in README.md [\#632](https://github.com/CosmWasm/cw-plus/pull/632) ([josefrichter](https://github.com/josefrichter)) -- Update ics20 contract [\#631](https://github.com/CosmWasm/cw-plus/pull/631) ([ethanfrey](https://github.com/ethanfrey)) -- Publish snapshot map changelog [\#622](https://github.com/CosmWasm/cw-plus/pull/622) ([maurolacy](https://github.com/maurolacy)) -- Remove `IntKey` and `TimestampKey` [\#620](https://github.com/CosmWasm/cw-plus/pull/620) ([ueco-jb](https://github.com/ueco-jb)) -- Signed int key benchmarks [\#619](https://github.com/CosmWasm/cw-plus/pull/619) ([maurolacy](https://github.com/maurolacy)) -- fix readme update coralnet to sandynet-1 [\#617](https://github.com/CosmWasm/cw-plus/pull/617) ([yubrew](https://github.com/yubrew)) -- Publish `PrefixBound` [\#616](https://github.com/CosmWasm/cw-plus/pull/616) ([maurolacy](https://github.com/maurolacy)) -- Move contracts to cw-tokens [\#613](https://github.com/CosmWasm/cw-plus/pull/613) ([ethanfrey](https://github.com/ethanfrey)) -- Add context to multitest execution errors [\#597](https://github.com/CosmWasm/cw-plus/pull/597) ([uint](https://github.com/uint)) +- Fix tag consolidation for matching CHANGELOG entries [\#634](https://github.com/CosmWasm/cw-plus/pull/634) + ([maurolacy](https://github.com/maurolacy)) +- Ics20 contract rollback [\#633](https://github.com/CosmWasm/cw-plus/pull/633) + ([ethanfrey](https://github.com/ethanfrey)) +- Fix typo in README.md [\#632](https://github.com/CosmWasm/cw-plus/pull/632) + ([josefrichter](https://github.com/josefrichter)) +- Update ics20 contract [\#631](https://github.com/CosmWasm/cw-plus/pull/631) + ([ethanfrey](https://github.com/ethanfrey)) +- Publish snapshot map changelog [\#622](https://github.com/CosmWasm/cw-plus/pull/622) + ([maurolacy](https://github.com/maurolacy)) +- Remove `IntKey` and `TimestampKey` [\#620](https://github.com/CosmWasm/cw-plus/pull/620) + ([ueco-jb](https://github.com/ueco-jb)) +- Signed int key benchmarks [\#619](https://github.com/CosmWasm/cw-plus/pull/619) + ([maurolacy](https://github.com/maurolacy)) +- fix readme update coralnet to sandynet-1 [\#617](https://github.com/CosmWasm/cw-plus/pull/617) + ([yubrew](https://github.com/yubrew)) +- Publish `PrefixBound` [\#616](https://github.com/CosmWasm/cw-plus/pull/616) + ([maurolacy](https://github.com/maurolacy)) +- Move contracts to cw-tokens [\#613](https://github.com/CosmWasm/cw-plus/pull/613) + ([ethanfrey](https://github.com/ethanfrey)) +- Add context to multitest execution errors [\#597](https://github.com/CosmWasm/cw-plus/pull/597) + ([uint](https://github.com/uint)) ## [v0.11.1](https://github.com/CosmWasm/cw-plus/tree/v0.11.1) (2021-12-28) @@ -392,14 +526,22 @@ **Merged pull requests:** -- Assert non-empty send/burn/mint in multitest bank module [\#611](https://github.com/CosmWasm/cw-plus/pull/611) ([ethanfrey](https://github.com/ethanfrey)) -- cw-storage-plus: Expose keys::Key [\#609](https://github.com/CosmWasm/cw-plus/pull/609) ([orkunkl](https://github.com/orkunkl)) -- Implement Expired variant, Scheduled [\#606](https://github.com/CosmWasm/cw-plus/pull/606) ([orkunkl](https://github.com/orkunkl)) -- Signed int keys migrate example [\#604](https://github.com/CosmWasm/cw-plus/pull/604) ([maurolacy](https://github.com/maurolacy)) -- Adjust order of publishing to handle new deps [\#603](https://github.com/CosmWasm/cw-plus/pull/603) ([ethanfrey](https://github.com/ethanfrey)) -- Fix cw-utils README entry [\#601](https://github.com/CosmWasm/cw-plus/pull/601) ([maurolacy](https://github.com/maurolacy)) -- Rename utils to cw-utils [\#598](https://github.com/CosmWasm/cw-plus/pull/598) ([ethanfrey](https://github.com/ethanfrey)) -- Mention latest workspace optimizer version in README [\#595](https://github.com/CosmWasm/cw-plus/pull/595) ([ueco-jb](https://github.com/ueco-jb)) +- Assert non-empty send/burn/mint in multitest bank module [\#611](https://github.com/CosmWasm/cw-plus/pull/611) + ([ethanfrey](https://github.com/ethanfrey)) +- cw-storage-plus: Expose keys::Key [\#609](https://github.com/CosmWasm/cw-plus/pull/609) + ([orkunkl](https://github.com/orkunkl)) +- Implement Expired variant, Scheduled [\#606](https://github.com/CosmWasm/cw-plus/pull/606) + ([orkunkl](https://github.com/orkunkl)) +- Signed int keys migrate example [\#604](https://github.com/CosmWasm/cw-plus/pull/604) + ([maurolacy](https://github.com/maurolacy)) +- Adjust order of publishing to handle new deps [\#603](https://github.com/CosmWasm/cw-plus/pull/603) + ([ethanfrey](https://github.com/ethanfrey)) +- Fix cw-utils README entry [\#601](https://github.com/CosmWasm/cw-plus/pull/601) + ([maurolacy](https://github.com/maurolacy)) +- Rename utils to cw-utils [\#598](https://github.com/CosmWasm/cw-plus/pull/598) + ([ethanfrey](https://github.com/ethanfrey)) +- Mention latest workspace optimizer version in README [\#595](https://github.com/CosmWasm/cw-plus/pull/595) + ([ueco-jb](https://github.com/ueco-jb)) ## [v0.11.0](https://github.com/CosmWasm/cw-plus/tree/v0.11.0) (2021-12-22) @@ -415,13 +557,15 @@ **Implemented enhancements:** - Add `MIGRATING.md` [\#583](https://github.com/CosmWasm/cw-plus/issues/583) -- Remove schemas, and publish them with artifacts on release tags [\#529](https://github.com/CosmWasm/cw-plus/issues/529) +- Remove schemas, and publish them with artifacts on release tags + [\#529](https://github.com/CosmWasm/cw-plus/issues/529) **Closed issues:** -- Check \(and possibly fix\) threshold and voting power implementation in `cw3-fixed-multisig` [\#551](https://github.com/CosmWasm/cw-plus/issues/551) +- Check \(and possibly fix\) threshold and voting power implementation in `cw3-fixed-multisig` + [\#551](https://github.com/CosmWasm/cw-plus/issues/551) - Update to cosmwasm 1.0.0-beta3 [\#579](https://github.com/CosmWasm/cw-plus/issues/579) -- Cannot import non "library" features in dev-dependencies [\#577](https://github.com/CosmWasm/cw-plus/issues/577) +- Cannot import non "library" features in dev-dependencies [\#577](https://github.com/CosmWasm/cw-plus/issues/577) - `base-helpers.ts` doesn't belong to `contracts` [\#566](https://github.com/CosmWasm/cw-plus/issues/566) - handle function [\#563](https://github.com/CosmWasm/cw-plus/issues/563) - Migrate from `IntKey` to new naked int key [\#549](https://github.com/CosmWasm/cw-plus/issues/549) @@ -439,35 +583,56 @@ **Merged pull requests:** - Add `MIGRATING.md` [\#591](https://github.com/CosmWasm/cw-plus/pull/591) ([maurolacy](https://github.com/maurolacy)) -- Move Threshold and coexisting implementations into packages/utils [\#590](https://github.com/CosmWasm/cw-plus/pull/590) ([ueco-jb](https://github.com/ueco-jb)) -- Build and upload schemas in CI [\#589](https://github.com/CosmWasm/cw-plus/pull/589) ([maurolacy](https://github.com/maurolacy)) -- Fix min threshold and vote power bugs in cw3-fixed-multisig [\#588](https://github.com/CosmWasm/cw-plus/pull/588) ([ueco-jb](https://github.com/ueco-jb)) -- Update to cosmwasm 1.0.0-beta3 [\#587](https://github.com/CosmWasm/cw-plus/pull/587) ([ueco-jb](https://github.com/ueco-jb)) -- Make `update_changelog.sh` use the latest version tag by default [\#585](https://github.com/CosmWasm/cw-plus/pull/585) ([maurolacy](https://github.com/maurolacy)) -- Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) ([maurolacy](https://github.com/maurolacy)) -- `range` to `range raw` [\#576](https://github.com/CosmWasm/cw-plus/pull/576) ([maurolacy](https://github.com/maurolacy)) -- Remove helper.ts files for contracts [\#574](https://github.com/CosmWasm/cw-plus/pull/574) ([findolor](https://github.com/findolor)) -- Fix expiration type properties on cw1-subkeys helpers.ts [\#571](https://github.com/CosmWasm/cw-plus/pull/571) ([findolor](https://github.com/findolor)) -- `MultiIndex` primary key spec removal [\#569](https://github.com/CosmWasm/cw-plus/pull/569) ([maurolacy](https://github.com/maurolacy)) -- Index keys consistency [\#568](https://github.com/CosmWasm/cw-plus/pull/568) ([maurolacy](https://github.com/maurolacy)) -- Implement display for Balance and Coin [\#565](https://github.com/CosmWasm/cw-plus/pull/565) ([orkunkl](https://github.com/orkunkl)) -- Migrate from `IntKey` to new naked int key [\#564](https://github.com/CosmWasm/cw-plus/pull/564) ([ueco-jb](https://github.com/ueco-jb)) -- Add ParseReplyError to cw0 lib [\#562](https://github.com/CosmWasm/cw-plus/pull/562) ([shanev](https://github.com/shanev)) -- Update cw2 readme - contract\_info key [\#561](https://github.com/CosmWasm/cw-plus/pull/561) ([korzewski](https://github.com/korzewski)) -- Change pebblenet to uni and update wasm binary to 0.10.2 [\#560](https://github.com/CosmWasm/cw-plus/pull/560) ([findolor](https://github.com/findolor)) -- Update cw1-subkeys/helpers.ts wasm binary version to 0.10.2 from 0.9.1 [\#558](https://github.com/CosmWasm/cw-plus/pull/558) ([findolor](https://github.com/findolor)) -- Update base-helpers.ts options [\#557](https://github.com/CosmWasm/cw-plus/pull/557) ([findolor](https://github.com/findolor)) -- Update cw4-group/helpers.ts to work with base-helpers.ts [\#552](https://github.com/CosmWasm/cw-plus/pull/552) ([findolor](https://github.com/findolor)) -- Update cw3-flex-multisig/helpers.ts to work with cosmjs/cli v0.26 and base-helpers.ts [\#550](https://github.com/CosmWasm/cw-plus/pull/550) ([findolor](https://github.com/findolor)) +- Move Threshold and coexisting implementations into packages/utils + [\#590](https://github.com/CosmWasm/cw-plus/pull/590) ([ueco-jb](https://github.com/ueco-jb)) +- Build and upload schemas in CI [\#589](https://github.com/CosmWasm/cw-plus/pull/589) + ([maurolacy](https://github.com/maurolacy)) +- Fix min threshold and vote power bugs in cw3-fixed-multisig [\#588](https://github.com/CosmWasm/cw-plus/pull/588) + ([ueco-jb](https://github.com/ueco-jb)) +- Update to cosmwasm 1.0.0-beta3 [\#587](https://github.com/CosmWasm/cw-plus/pull/587) + ([ueco-jb](https://github.com/ueco-jb)) +- Make `update_changelog.sh` use the latest version tag by default [\#585](https://github.com/CosmWasm/cw-plus/pull/585) + ([maurolacy](https://github.com/maurolacy)) +- Signed int keys order [\#582](https://github.com/CosmWasm/cw-plus/pull/582) + ([maurolacy](https://github.com/maurolacy)) +- `range` to `range raw` [\#576](https://github.com/CosmWasm/cw-plus/pull/576) + ([maurolacy](https://github.com/maurolacy)) +- Remove helper.ts files for contracts [\#574](https://github.com/CosmWasm/cw-plus/pull/574) + ([findolor](https://github.com/findolor)) +- Fix expiration type properties on cw1-subkeys helpers.ts [\#571](https://github.com/CosmWasm/cw-plus/pull/571) + ([findolor](https://github.com/findolor)) +- `MultiIndex` primary key spec removal [\#569](https://github.com/CosmWasm/cw-plus/pull/569) + ([maurolacy](https://github.com/maurolacy)) +- Index keys consistency [\#568](https://github.com/CosmWasm/cw-plus/pull/568) + ([maurolacy](https://github.com/maurolacy)) +- Implement display for Balance and Coin [\#565](https://github.com/CosmWasm/cw-plus/pull/565) + ([orkunkl](https://github.com/orkunkl)) +- Migrate from `IntKey` to new naked int key [\#564](https://github.com/CosmWasm/cw-plus/pull/564) + ([ueco-jb](https://github.com/ueco-jb)) +- Add ParseReplyError to cw0 lib [\#562](https://github.com/CosmWasm/cw-plus/pull/562) + ([shanev](https://github.com/shanev)) +- Update cw2 readme - contract_info key [\#561](https://github.com/CosmWasm/cw-plus/pull/561) + ([korzewski](https://github.com/korzewski)) +- Change pebblenet to uni and update wasm binary to 0.10.2 [\#560](https://github.com/CosmWasm/cw-plus/pull/560) + ([findolor](https://github.com/findolor)) +- Update cw1-subkeys/helpers.ts wasm binary version to 0.10.2 from 0.9.1 + [\#558](https://github.com/CosmWasm/cw-plus/pull/558) ([findolor](https://github.com/findolor)) +- Update base-helpers.ts options [\#557](https://github.com/CosmWasm/cw-plus/pull/557) + ([findolor](https://github.com/findolor)) +- Update cw4-group/helpers.ts to work with base-helpers.ts [\#552](https://github.com/CosmWasm/cw-plus/pull/552) + ([findolor](https://github.com/findolor)) +- Update cw3-flex-multisig/helpers.ts to work with cosmjs/cli v0.26 and base-helpers.ts + [\#550](https://github.com/CosmWasm/cw-plus/pull/550) ([findolor](https://github.com/findolor)) - Cw0 rename [\#508](https://github.com/CosmWasm/cw-plus/pull/508) ([maurolacy](https://github.com/maurolacy)) -- UniqueIndex range\_de [\#500](https://github.com/CosmWasm/cw-plus/pull/500) ([uint](https://github.com/uint)) +- UniqueIndex range_de [\#500](https://github.com/CosmWasm/cw-plus/pull/500) ([uint](https://github.com/uint)) ## [v0.10.3](https://github.com/CosmWasm/cw-plus/tree/v0.10.3) (2021-11-16) **Implemented enhancements:** - Deprecate IntKey [\#547](https://github.com/CosmWasm/cw-plus/pull/547) ([ueco-jb](https://github.com/ueco-jb)) -- Implement WasmQuery::ContractInfo [\#554](https://github.com/CosmWasm/cw-plus/pull/554) ([ethanfrey](https://github.com/ethanfrey)) +- Implement WasmQuery::ContractInfo [\#554](https://github.com/CosmWasm/cw-plus/pull/554) + ([ethanfrey](https://github.com/ethanfrey)) **Fixed bugs:** @@ -483,14 +648,21 @@ **Merged pull requests:** -- Update cw1-subkeys/helpers.ts file to work with cosmjs/cli v0.26 [\#546](https://github.com/CosmWasm/cw-plus/pull/546) ([findolor](https://github.com/findolor)) +- Update cw1-subkeys/helpers.ts file to work with cosmjs/cli v0.26 [\#546](https://github.com/CosmWasm/cw-plus/pull/546) + ([findolor](https://github.com/findolor)) - Fix cw20 readme [\#544](https://github.com/CosmWasm/cw-plus/pull/544) ([loloicci](https://github.com/loloicci)) -- Revert "Update helper version and refactor based on new base helper" [\#538](https://github.com/CosmWasm/cw-plus/pull/538) ([findolor](https://github.com/findolor)) -- Update cw1-subkeys/helpers.ts version and refactor based on base-helper.ts [\#537](https://github.com/CosmWasm/cw-plus/pull/537) ([findolor](https://github.com/findolor)) -- Refactor cw20-base/helpers.ts based on base-helper.ts [\#536](https://github.com/CosmWasm/cw-plus/pull/536) ([findolor](https://github.com/findolor)) -- Add base helper for contracts [\#535](https://github.com/CosmWasm/cw-plus/pull/535) ([findolor](https://github.com/findolor)) -- Fix min threshold in cw3-flex-multisig [\#528](https://github.com/CosmWasm/cw-plus/pull/528) ([ueco-jb](https://github.com/ueco-jb)) -- cw1-subkeys: Migration example [\#525](https://github.com/CosmWasm/cw-plus/pull/525) ([hashedone](https://github.com/hashedone)) +- Revert "Update helper version and refactor based on new base helper" + [\#538](https://github.com/CosmWasm/cw-plus/pull/538) ([findolor](https://github.com/findolor)) +- Update cw1-subkeys/helpers.ts version and refactor based on base-helper.ts + [\#537](https://github.com/CosmWasm/cw-plus/pull/537) ([findolor](https://github.com/findolor)) +- Refactor cw20-base/helpers.ts based on base-helper.ts [\#536](https://github.com/CosmWasm/cw-plus/pull/536) + ([findolor](https://github.com/findolor)) +- Add base helper for contracts [\#535](https://github.com/CosmWasm/cw-plus/pull/535) + ([findolor](https://github.com/findolor)) +- Fix min threshold in cw3-flex-multisig [\#528](https://github.com/CosmWasm/cw-plus/pull/528) + ([ueco-jb](https://github.com/ueco-jb)) +- cw1-subkeys: Migration example [\#525](https://github.com/CosmWasm/cw-plus/pull/525) + ([hashedone](https://github.com/hashedone)) ## [v0.10.2](https://github.com/CosmWasm/cw-plus/tree/v0.10.2) (2021-11-03) @@ -500,14 +672,22 @@ **Merged pull requests:** -- cw1-whitelist-ng: Slight messages parsing improvement [\#523](https://github.com/CosmWasm/cw-plus/pull/523) ([hashedone](https://github.com/hashedone)) -- ics20: Handle send errors with reply [\#520](https://github.com/CosmWasm/cw-plus/pull/520) ([ethanfrey](https://github.com/ethanfrey)) -- Proper execute responses [\#519](https://github.com/CosmWasm/cw-plus/pull/519) ([ethanfrey](https://github.com/ethanfrey)) -- Publish MsgInstantiate / Execute responses [\#518](https://github.com/CosmWasm/cw-plus/pull/518) ([maurolacy](https://github.com/maurolacy)) -- Fix instaniate reply data [\#517](https://github.com/CosmWasm/cw-plus/pull/517) ([ethanfrey](https://github.com/ethanfrey)) -- Use protobuf de helpers [\#515](https://github.com/CosmWasm/cw-plus/pull/515) ([maurolacy](https://github.com/maurolacy)) -- Add tests for the claims controller [\#514](https://github.com/CosmWasm/cw-plus/pull/514) ([sgoya](https://github.com/sgoya)) -- Implement cw3-flex-multisig helper [\#479](https://github.com/CosmWasm/cw-plus/pull/479) ([orkunkl](https://github.com/orkunkl)) +- cw1-whitelist-ng: Slight messages parsing improvement [\#523](https://github.com/CosmWasm/cw-plus/pull/523) + ([hashedone](https://github.com/hashedone)) +- ics20: Handle send errors with reply [\#520](https://github.com/CosmWasm/cw-plus/pull/520) + ([ethanfrey](https://github.com/ethanfrey)) +- Proper execute responses [\#519](https://github.com/CosmWasm/cw-plus/pull/519) + ([ethanfrey](https://github.com/ethanfrey)) +- Publish MsgInstantiate / Execute responses [\#518](https://github.com/CosmWasm/cw-plus/pull/518) + ([maurolacy](https://github.com/maurolacy)) +- Fix instaniate reply data [\#517](https://github.com/CosmWasm/cw-plus/pull/517) + ([ethanfrey](https://github.com/ethanfrey)) +- Use protobuf de helpers [\#515](https://github.com/CosmWasm/cw-plus/pull/515) + ([maurolacy](https://github.com/maurolacy)) +- Add tests for the claims controller [\#514](https://github.com/CosmWasm/cw-plus/pull/514) + ([sgoya](https://github.com/sgoya)) +- Implement cw3-flex-multisig helper [\#479](https://github.com/CosmWasm/cw-plus/pull/479) + ([orkunkl](https://github.com/orkunkl)) ## [v0.10.1](https://github.com/CosmWasm/cw-plus/tree/v0.10.1) (2021-10-26) @@ -515,21 +695,29 @@ **Closed issues:** -- Reimplement cw1-whitelist contract in terms of semantic structures [\#494](https://github.com/CosmWasm/cw-plus/issues/494) +- Reimplement cw1-whitelist contract in terms of semantic structures + [\#494](https://github.com/CosmWasm/cw-plus/issues/494) - Helper transfer method failed to execute message [\#492](https://github.com/CosmWasm/cw-plus/issues/492) -- Add helpers for parsing the protobuf MsgInstantiate and MsgExecute responses [\#480](https://github.com/CosmWasm/cw-plus/issues/480) +- Add helpers for parsing the protobuf MsgInstantiate and MsgExecute responses + [\#480](https://github.com/CosmWasm/cw-plus/issues/480) **Merged pull requests:** -- Prepare 0.10.1 release [\#513](https://github.com/CosmWasm/cw-plus/pull/513) ([ethanfrey](https://github.com/ethanfrey)) -- Added cw1-whitelist-ng to CI [\#512](https://github.com/CosmWasm/cw-plus/pull/512) ([hashedone](https://github.com/hashedone)) -- cw1-subkeys-ng: Additional follow up improvements [\#506](https://github.com/CosmWasm/cw-plus/pull/506) ([hashedone](https://github.com/hashedone)) +- Prepare 0.10.1 release [\#513](https://github.com/CosmWasm/cw-plus/pull/513) + ([ethanfrey](https://github.com/ethanfrey)) +- Added cw1-whitelist-ng to CI [\#512](https://github.com/CosmWasm/cw-plus/pull/512) + ([hashedone](https://github.com/hashedone)) +- cw1-subkeys-ng: Additional follow up improvements [\#506](https://github.com/CosmWasm/cw-plus/pull/506) + ([hashedone](https://github.com/hashedone)) - Parse reply helpers [\#502](https://github.com/CosmWasm/cw-plus/pull/502) ([maurolacy](https://github.com/maurolacy)) -- cw1-whitelist-ng: Contract implementation in terms of semantical structures [\#499](https://github.com/CosmWasm/cw-plus/pull/499) ([hashedone](https://github.com/hashedone)) -- range\_de for IndexMap [\#498](https://github.com/CosmWasm/cw-plus/pull/498) ([uint](https://github.com/uint)) -- Implement range\_de for SnapshotMap [\#497](https://github.com/CosmWasm/cw-plus/pull/497) ([uint](https://github.com/uint)) +- cw1-whitelist-ng: Contract implementation in terms of semantical structures + [\#499](https://github.com/CosmWasm/cw-plus/pull/499) ([hashedone](https://github.com/hashedone)) +- range_de for IndexMap [\#498](https://github.com/CosmWasm/cw-plus/pull/498) ([uint](https://github.com/uint)) +- Implement range_de for SnapshotMap [\#497](https://github.com/CosmWasm/cw-plus/pull/497) + ([uint](https://github.com/uint)) - Fix publish script [\#486](https://github.com/CosmWasm/cw-plus/pull/486) ([ethanfrey](https://github.com/ethanfrey)) -- Implement cw4-group typescript helper [\#476](https://github.com/CosmWasm/cw-plus/pull/476) ([orkunkl](https://github.com/orkunkl)) +- Implement cw4-group typescript helper [\#476](https://github.com/CosmWasm/cw-plus/pull/476) + ([orkunkl](https://github.com/orkunkl)) ## [v0.10.0](https://github.com/CosmWasm/cw-plus/tree/v0.10.0) (2021-10-11) @@ -541,9 +729,11 @@ - More multitest improvements [\#266](https://github.com/CosmWasm/cw-plus/issues/266) - Update to cosmwasm v1.0.0-soon2 [\#473](https://github.com/CosmWasm/cw-plus/issues/473) - Allow NFTs to include custom data [\#440](https://github.com/CosmWasm/cw-plus/issues/440) -- Refactor Admin cw-controller to better represent actual functionality [\#424](https://github.com/CosmWasm/cw-plus/issues/424) +- Refactor Admin cw-controller to better represent actual functionality + [\#424](https://github.com/CosmWasm/cw-plus/issues/424) - Implement `PrimaryKey` for `Timestamp` [\#419](https://github.com/CosmWasm/cw-plus/issues/419) -- storage-plus: Improve in-code documentation of map primitives, in particular `MultiIndex` [\#407](https://github.com/CosmWasm/cw-plus/issues/407) +- storage-plus: Improve in-code documentation of map primitives, in particular `MultiIndex` + [\#407](https://github.com/CosmWasm/cw-plus/issues/407) - Remove use of dyn in multitest Router [\#404](https://github.com/CosmWasm/cw-plus/issues/404) - Define generic multitest module [\#387](https://github.com/CosmWasm/cw-plus/issues/387) @@ -551,8 +741,10 @@ - Update CHANGELOG [\#485](https://github.com/CosmWasm/cw-plus/pull/485) ([ethanfrey](https://github.com/ethanfrey)) - Release 0.10.0 [\#483](https://github.com/CosmWasm/cw-plus/pull/483) ([ethanfrey](https://github.com/ethanfrey)) -- Upgrade CosmWasm to 1.0.0-beta [\#482](https://github.com/CosmWasm/cw-plus/pull/482) ([webmaster128](https://github.com/webmaster128)) -- Full deserialization for `range` [\#432](https://github.com/CosmWasm/cw-plus/pull/432) ([maurolacy](https://github.com/maurolacy)) +- Upgrade CosmWasm to 1.0.0-beta [\#482](https://github.com/CosmWasm/cw-plus/pull/482) + ([webmaster128](https://github.com/webmaster128)) +- Full deserialization for `range` [\#432](https://github.com/CosmWasm/cw-plus/pull/432) + ([maurolacy](https://github.com/maurolacy)) ## [v0.10.0-soon4](https://github.com/CosmWasm/cw-plus/tree/v0.10.0-soon4) (2021-10-07) @@ -560,7 +752,8 @@ **Fixed bugs:** -- Fix improper assert\_matches usage [\#459](https://github.com/CosmWasm/cw-plus/pull/459) ([ueco-jb](https://github.com/ueco-jb)) +- Fix improper assert_matches usage [\#459](https://github.com/CosmWasm/cw-plus/pull/459) + ([ueco-jb](https://github.com/ueco-jb)) **Closed issues:** @@ -570,15 +763,22 @@ **Merged pull requests:** -- Release v0.10.0-soon4 [\#477](https://github.com/CosmWasm/cw-plus/pull/477) ([ethanfrey](https://github.com/ethanfrey)) -- Update to CosmWasm 1.0.0-soon2 [\#475](https://github.com/CosmWasm/cw-plus/pull/475) ([ethanfrey](https://github.com/ethanfrey)) -- Allow error type conversions in ensure! and ensure\_eq! [\#474](https://github.com/CosmWasm/cw-plus/pull/474) ([webmaster128](https://github.com/webmaster128)) -- Improve error handling / remove FIXMEs [\#470](https://github.com/CosmWasm/cw-plus/pull/470) ([maurolacy](https://github.com/maurolacy)) +- Release v0.10.0-soon4 [\#477](https://github.com/CosmWasm/cw-plus/pull/477) + ([ethanfrey](https://github.com/ethanfrey)) +- Update to CosmWasm 1.0.0-soon2 [\#475](https://github.com/CosmWasm/cw-plus/pull/475) + ([ethanfrey](https://github.com/ethanfrey)) +- Allow error type conversions in ensure! and ensure_eq! [\#474](https://github.com/CosmWasm/cw-plus/pull/474) + ([webmaster128](https://github.com/webmaster128)) +- Improve error handling / remove FIXMEs [\#470](https://github.com/CosmWasm/cw-plus/pull/470) + ([maurolacy](https://github.com/maurolacy)) - Add ensure [\#469](https://github.com/CosmWasm/cw-plus/pull/469) ([ethanfrey](https://github.com/ethanfrey)) -- Key deserializer improvements [\#467](https://github.com/CosmWasm/cw-plus/pull/467) ([maurolacy](https://github.com/maurolacy)) -- Upgrade to cosmwasm/workspace-optimizer:0.12.3 [\#465](https://github.com/CosmWasm/cw-plus/pull/465) ([webmaster128](https://github.com/webmaster128)) +- Key deserializer improvements [\#467](https://github.com/CosmWasm/cw-plus/pull/467) + ([maurolacy](https://github.com/maurolacy)) +- Upgrade to cosmwasm/workspace-optimizer:0.12.3 [\#465](https://github.com/CosmWasm/cw-plus/pull/465) + ([webmaster128](https://github.com/webmaster128)) - Prefix consolidation [\#439](https://github.com/CosmWasm/cw-plus/pull/439) ([maurolacy](https://github.com/maurolacy)) -- Full deserialization for `range` [\#432](https://github.com/CosmWasm/cw-plus/pull/432) ([maurolacy](https://github.com/maurolacy)) +- Full deserialization for `range` [\#432](https://github.com/CosmWasm/cw-plus/pull/432) + ([maurolacy](https://github.com/maurolacy)) ## [v0.10.0-soon3](https://github.com/CosmWasm/cw-plus/tree/v0.10.0-soon3) (2021-09-29) @@ -586,8 +786,10 @@ **Merged pull requests:** -- Prepare release v0.10.0-soon3 [\#457](https://github.com/CosmWasm/cw-plus/pull/457) ([ethanfrey](https://github.com/ethanfrey)) -- Expose essential multitest types [\#456](https://github.com/CosmWasm/cw-plus/pull/456) ([ethanfrey](https://github.com/ethanfrey)) +- Prepare release v0.10.0-soon3 [\#457](https://github.com/CosmWasm/cw-plus/pull/457) + ([ethanfrey](https://github.com/ethanfrey)) +- Expose essential multitest types [\#456](https://github.com/CosmWasm/cw-plus/pull/456) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.10.0-soon2](https://github.com/CosmWasm/cw-plus/tree/v0.10.0-soon2) (2021-09-28) @@ -596,9 +798,12 @@ **Merged pull requests:** - Release 0.10.0-soon2 [\#455](https://github.com/CosmWasm/cw-plus/pull/455) ([ethanfrey](https://github.com/ethanfrey)) -- Expose sudo powers on Router we give to Modules [\#453](https://github.com/CosmWasm/cw-plus/pull/453) ([ethanfrey](https://github.com/ethanfrey)) -- Forward port 440 demo metadata extension [\#452](https://github.com/CosmWasm/cw-plus/pull/452) ([ethanfrey](https://github.com/ethanfrey)) -- Forward port 440-customize-nft [\#451](https://github.com/CosmWasm/cw-plus/pull/451) ([ethanfrey](https://github.com/ethanfrey)) +- Expose sudo powers on Router we give to Modules [\#453](https://github.com/CosmWasm/cw-plus/pull/453) + ([ethanfrey](https://github.com/ethanfrey)) +- Forward port 440 demo metadata extension [\#452](https://github.com/CosmWasm/cw-plus/pull/452) + ([ethanfrey](https://github.com/ethanfrey)) +- Forward port 440-customize-nft [\#451](https://github.com/CosmWasm/cw-plus/pull/451) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.9.1](https://github.com/CosmWasm/cw-plus/tree/v0.9.1) (2021-09-23) @@ -618,32 +823,44 @@ - small updates on storage-plus docs [\#435](https://github.com/CosmWasm/cw-plus/issues/435) - Unintuitive behavior of range on multi-index [\#430](https://github.com/CosmWasm/cw-plus/issues/430) - Upgrade to cosmwasm 1.0-soon [\#427](https://github.com/CosmWasm/cw-plus/issues/427) -- Refactor Admin cw-controller to better represent actual functionality [\#424](https://github.com/CosmWasm/cw-plus/issues/424) +- Refactor Admin cw-controller to better represent actual functionality + [\#424](https://github.com/CosmWasm/cw-plus/issues/424) - Add auto-changelog generator [\#421](https://github.com/CosmWasm/cw-plus/issues/421) - Implement `PrimaryKey` for `Timestamp` [\#419](https://github.com/CosmWasm/cw-plus/issues/419) -- storage-plus: Improve in-code documentation of map primitives, in particular `MultiIndex` [\#407](https://github.com/CosmWasm/cw-plus/issues/407) +- storage-plus: Improve in-code documentation of map primitives, in particular `MultiIndex` + [\#407](https://github.com/CosmWasm/cw-plus/issues/407) - Remove use of dyn in multitest Router [\#404](https://github.com/CosmWasm/cw-plus/issues/404) - Define generic multitest module [\#387](https://github.com/CosmWasm/cw-plus/issues/387) -- Cw20 state key compatibity with previous versions [\#346](https://github.com/CosmWasm/cw-plus/issues/346) +- Cw20 state key compatibity with previous versions [\#346](https://github.com/CosmWasm/cw-plus/issues/346) - Refactor cw20-base to use controller pattern [\#205](https://github.com/CosmWasm/cw-plus/issues/205) **Merged pull requests:** - Release 0.10.0-soon [\#448](https://github.com/CosmWasm/cw-plus/pull/448) ([ethanfrey](https://github.com/ethanfrey)) -- Add proper prefix\_range helper when you want to iterate over the prefix space [\#446](https://github.com/CosmWasm/cw-plus/pull/446) ([ethanfrey](https://github.com/ethanfrey)) -- Improve in-code documentation of map primitives [\#443](https://github.com/CosmWasm/cw-plus/pull/443) ([ueco-jb](https://github.com/ueco-jb)) -- Small storage-plus docs update [\#442](https://github.com/CosmWasm/cw-plus/pull/442) ([hashedone](https://github.com/hashedone)) -- Upgrade to cosmwasm 1.0.0-soon [\#441](https://github.com/CosmWasm/cw-plus/pull/441) ([ethanfrey](https://github.com/ethanfrey)) -- Test storage-plus with iterator disabled [\#438](https://github.com/CosmWasm/cw-plus/pull/438) ([ethanfrey](https://github.com/ethanfrey)) -- Multitest module query [\#437](https://github.com/CosmWasm/cw-plus/pull/437) ([ethanfrey](https://github.com/ethanfrey)) -- Range with no prefix support [\#433](https://github.com/CosmWasm/cw-plus/pull/433) ([maurolacy](https://github.com/maurolacy)) -- Added implementation of timestamp key [\#431](https://github.com/CosmWasm/cw-plus/pull/431) ([hashedone](https://github.com/hashedone)) +- Add proper prefix_range helper when you want to iterate over the prefix space + [\#446](https://github.com/CosmWasm/cw-plus/pull/446) ([ethanfrey](https://github.com/ethanfrey)) +- Improve in-code documentation of map primitives [\#443](https://github.com/CosmWasm/cw-plus/pull/443) + ([ueco-jb](https://github.com/ueco-jb)) +- Small storage-plus docs update [\#442](https://github.com/CosmWasm/cw-plus/pull/442) + ([hashedone](https://github.com/hashedone)) +- Upgrade to cosmwasm 1.0.0-soon [\#441](https://github.com/CosmWasm/cw-plus/pull/441) + ([ethanfrey](https://github.com/ethanfrey)) +- Test storage-plus with iterator disabled [\#438](https://github.com/CosmWasm/cw-plus/pull/438) + ([ethanfrey](https://github.com/ethanfrey)) +- Multitest module query [\#437](https://github.com/CosmWasm/cw-plus/pull/437) + ([ethanfrey](https://github.com/ethanfrey)) +- Range with no prefix support [\#433](https://github.com/CosmWasm/cw-plus/pull/433) + ([maurolacy](https://github.com/maurolacy)) +- Added implementation of timestamp key [\#431](https://github.com/CosmWasm/cw-plus/pull/431) + ([hashedone](https://github.com/hashedone)) - Update changelog 2 [\#428](https://github.com/CosmWasm/cw-plus/pull/428) ([maurolacy](https://github.com/maurolacy)) -- Add automatically generated changelog [\#426](https://github.com/CosmWasm/cw-plus/pull/426) ([ueco-jb](https://github.com/ueco-jb)) +- Add automatically generated changelog [\#426](https://github.com/CosmWasm/cw-plus/pull/426) + ([ueco-jb](https://github.com/ueco-jb)) - Generic module types [\#425](https://github.com/CosmWasm/cw-plus/pull/425) ([ethanfrey](https://github.com/ethanfrey)) - Simplify router args [\#422](https://github.com/CosmWasm/cw-plus/pull/422) ([ethanfrey](https://github.com/ethanfrey)) - Snapshot item 2 [\#418](https://github.com/CosmWasm/cw-plus/pull/418) ([maurolacy](https://github.com/maurolacy)) -- Removing dyn from Router [\#410](https://github.com/CosmWasm/cw-plus/pull/410) ([hashedone](https://github.com/hashedone)) +- Removing dyn from Router [\#410](https://github.com/CosmWasm/cw-plus/pull/410) + ([hashedone](https://github.com/hashedone)) ## [v0.9.0](https://github.com/CosmWasm/cw-plus/tree/v0.9.0) (2021-09-14) @@ -651,9 +868,11 @@ **Implemented enhancements:** -- Move from using unsound `from_utf8_unchecked` to safe `from_utf8` forwarding error [\#393](https://github.com/CosmWasm/cw-plus/issues/393) +- Move from using unsound `from_utf8_unchecked` to safe `from_utf8` forwarding error + [\#393](https://github.com/CosmWasm/cw-plus/issues/393) - Raw Query: make usage simpler and visible [\#325](https://github.com/CosmWasm/cw-plus/issues/325) -- Consider replacing `String` errors with `anyhow::Error` in interfaces [\#361](https://github.com/CosmWasm/cw-plus/issues/361) +- Consider replacing `String` errors with `anyhow::Error` in interfaces + [\#361](https://github.com/CosmWasm/cw-plus/issues/361) **Closed issues:** @@ -666,24 +885,36 @@ - Idea: item query helper storage helper [\#376](https://github.com/CosmWasm/cw-plus/issues/376) - Why you use `Addr` as keys in Maps? [\#295](https://github.com/CosmWasm/cw-plus/issues/295) - Add SnapshotItem to storage-plus [\#193](https://github.com/CosmWasm/cw-plus/issues/193) -- Fix lifetime of MultiIndex/UniqueIndex to be able to accept &str [\#232](https://github.com/CosmWasm/cw-plus/issues/232) +- Fix lifetime of MultiIndex/UniqueIndex to be able to accept &str + [\#232](https://github.com/CosmWasm/cw-plus/issues/232) - Unify multisig structs Member and VoterResponse [\#151](https://github.com/CosmWasm/cw-plus/issues/151) **Merged pull requests:** -- admin and hooks return Response\ in execute\_\* [\#417](https://github.com/CosmWasm/cw-plus/pull/417) ([ethanfrey](https://github.com/ethanfrey)) +- admin and hooks return Response\ in execute\_\* [\#417](https://github.com/CosmWasm/cw-plus/pull/417) + ([ethanfrey](https://github.com/ethanfrey)) - Release 0.9.0 [\#416](https://github.com/CosmWasm/cw-plus/pull/416) ([ethanfrey](https://github.com/ethanfrey)) -- Add send and sendFrom to cw20-base helpers.ts [\#415](https://github.com/CosmWasm/cw-plus/pull/415) ([orkunkl](https://github.com/orkunkl)) -- Add doc entry about key usage in maps [\#413](https://github.com/CosmWasm/cw-plus/pull/413) ([maurolacy](https://github.com/maurolacy)) -- Add query helpers to Item and Map and use them in cw4 helpers [\#412](https://github.com/CosmWasm/cw-plus/pull/412) ([ethanfrey](https://github.com/ethanfrey)) -- Update Cargo.toml files to reference new repo name [\#411](https://github.com/CosmWasm/cw-plus/pull/411) ([ueco-jb](https://github.com/ueco-jb)) +- Add send and sendFrom to cw20-base helpers.ts [\#415](https://github.com/CosmWasm/cw-plus/pull/415) + ([orkunkl](https://github.com/orkunkl)) +- Add doc entry about key usage in maps [\#413](https://github.com/CosmWasm/cw-plus/pull/413) + ([maurolacy](https://github.com/maurolacy)) +- Add query helpers to Item and Map and use them in cw4 helpers [\#412](https://github.com/CosmWasm/cw-plus/pull/412) + ([ethanfrey](https://github.com/ethanfrey)) +- Update Cargo.toml files to reference new repo name [\#411](https://github.com/CosmWasm/cw-plus/pull/411) + ([ueco-jb](https://github.com/ueco-jb)) - Snapshot item [\#409](https://github.com/CosmWasm/cw-plus/pull/409) ([maurolacy](https://github.com/maurolacy)) -- cw20-base: upgrade helper.ts to cosmjs 0.26.0 [\#406](https://github.com/CosmWasm/cw-plus/pull/406) ([spacepotahto](https://github.com/spacepotahto)) -- CW1-whitelist execute multitest [\#402](https://github.com/CosmWasm/cw-plus/pull/402) ([ueco-jb](https://github.com/ueco-jb)) -- Implementing all messages handling in mutlitest App [\#398](https://github.com/CosmWasm/cw-plus/pull/398) ([hashedone](https://github.com/hashedone)) -- Make it easier to assert events on reply statements [\#395](https://github.com/CosmWasm/cw-plus/pull/395) ([ethanfrey](https://github.com/ethanfrey)) -- Add helpers to check events [\#392](https://github.com/CosmWasm/cw-plus/pull/392) ([ethanfrey](https://github.com/ethanfrey)) -- Switching from String to anyhow::Error for error type in multi-test [\#389](https://github.com/CosmWasm/cw-plus/pull/389) ([hashedone](https://github.com/hashedone)) +- cw20-base: upgrade helper.ts to cosmjs 0.26.0 [\#406](https://github.com/CosmWasm/cw-plus/pull/406) + ([spacepotahto](https://github.com/spacepotahto)) +- CW1-whitelist execute multitest [\#402](https://github.com/CosmWasm/cw-plus/pull/402) + ([ueco-jb](https://github.com/ueco-jb)) +- Implementing all messages handling in mutlitest App [\#398](https://github.com/CosmWasm/cw-plus/pull/398) + ([hashedone](https://github.com/hashedone)) +- Make it easier to assert events on reply statements [\#395](https://github.com/CosmWasm/cw-plus/pull/395) + ([ethanfrey](https://github.com/ethanfrey)) +- Add helpers to check events [\#392](https://github.com/CosmWasm/cw-plus/pull/392) + ([ethanfrey](https://github.com/ethanfrey)) +- Switching from String to anyhow::Error for error type in multi-test + [\#389](https://github.com/CosmWasm/cw-plus/pull/389) ([hashedone](https://github.com/hashedone)) ## [v0.8.1](https://github.com/CosmWasm/cw-plus/tree/v0.8.1) (2021-08-26) @@ -691,11 +922,13 @@ **Implemented enhancements:** -- Consider replacing `String` errors with `anyhow::Error` in interfaces [\#361](https://github.com/CosmWasm/cw-plus/issues/361) +- Consider replacing `String` errors with `anyhow::Error` in interfaces + [\#361](https://github.com/CosmWasm/cw-plus/issues/361) **Closed issues:** -- Fix lifetime of MultiIndex/UniqueIndex to be able to accept &str [\#232](https://github.com/CosmWasm/cw-plus/issues/232) +- Fix lifetime of MultiIndex/UniqueIndex to be able to accept &str + [\#232](https://github.com/CosmWasm/cw-plus/issues/232) - Unify multisig structs Member and VoterResponse [\#151](https://github.com/CosmWasm/cw-plus/issues/151) - Add exhaustive checks for errors in contracts [\#105](https://github.com/CosmWasm/cw-plus/issues/105) @@ -708,11 +941,13 @@ - Upgrade CosmWasm to 0.16.0 [\#377](https://github.com/CosmWasm/cw-plus/issues/377) - Upgrade rust to 1.53 [\#372](https://github.com/CosmWasm/cw-plus/issues/372) - Implement cw20 logo spec for cw20-base [\#371](https://github.com/CosmWasm/cw-plus/issues/371) -- multi-test: ensure event handling matches wasmd 0.18 implementation [\#348](https://github.com/CosmWasm/cw-plus/issues/348) +- multi-test: ensure event handling matches wasmd 0.18 implementation + [\#348](https://github.com/CosmWasm/cw-plus/issues/348) **Merged pull requests:** -- Added some missing traits on messages of cw20-base [\#386](https://github.com/CosmWasm/cw-plus/pull/386) ([hashedone](https://github.com/hashedone)) +- Added some missing traits on messages of cw20-base [\#386](https://github.com/CosmWasm/cw-plus/pull/386) + ([hashedone](https://github.com/hashedone)) ## [v0.8.0-rc3](https://github.com/CosmWasm/cw-plus/tree/v0.8.0-rc3) (2021-08-10) @@ -720,14 +955,19 @@ **Closed issues:** -- multi-test: ensure event handling matches wasmd 0.18 implementation [\#348](https://github.com/CosmWasm/cw-plus/issues/348) +- multi-test: ensure event handling matches wasmd 0.18 implementation + [\#348](https://github.com/CosmWasm/cw-plus/issues/348) **Merged pull requests:** -- Corrected submessage data response handling in multi-test [\#385](https://github.com/CosmWasm/cw-plus/pull/385) ([hashedone](https://github.com/hashedone)) -- Document submsg data failures and fix them [\#383](https://github.com/CosmWasm/cw-plus/pull/383) ([ethanfrey](https://github.com/ethanfrey)) -- Adaptors for all contracts and entry points from Empty -\> C [\#382](https://github.com/CosmWasm/cw-plus/pull/382) ([ethanfrey](https://github.com/ethanfrey)) -- Multitest events match wasmd [\#380](https://github.com/CosmWasm/cw-plus/pull/380) ([ethanfrey](https://github.com/ethanfrey)) +- Corrected submessage data response handling in multi-test [\#385](https://github.com/CosmWasm/cw-plus/pull/385) + ([hashedone](https://github.com/hashedone)) +- Document submsg data failures and fix them [\#383](https://github.com/CosmWasm/cw-plus/pull/383) + ([ethanfrey](https://github.com/ethanfrey)) +- Adaptors for all contracts and entry points from Empty -\> C [\#382](https://github.com/CosmWasm/cw-plus/pull/382) + ([ethanfrey](https://github.com/ethanfrey)) +- Multitest events match wasmd [\#380](https://github.com/CosmWasm/cw-plus/pull/380) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.8.0-rc2](https://github.com/CosmWasm/cw-plus/tree/v0.8.0-rc2) (2021-08-05) @@ -747,18 +987,29 @@ **Merged pull requests:** - Update to Rust 1.53 [\#379](https://github.com/CosmWasm/cw-plus/pull/379) ([ethanfrey](https://github.com/ethanfrey)) -- Upgrade to cosmwasm 0.16 [\#378](https://github.com/CosmWasm/cw-plus/pull/378) ([ethanfrey](https://github.com/ethanfrey)) -- Marketing info for cw20-base contract [\#375](https://github.com/CosmWasm/cw-plus/pull/375) ([hashedone](https://github.com/hashedone)) -- cw20-merkle-airdrop: change hashing to sha256 [\#374](https://github.com/CosmWasm/cw-plus/pull/374) ([orkunkl](https://github.com/orkunkl)) -- Responses validation in multi-test [\#373](https://github.com/CosmWasm/cw-plus/pull/373) ([hashedone](https://github.com/hashedone)) +- Upgrade to cosmwasm 0.16 [\#378](https://github.com/CosmWasm/cw-plus/pull/378) + ([ethanfrey](https://github.com/ethanfrey)) +- Marketing info for cw20-base contract [\#375](https://github.com/CosmWasm/cw-plus/pull/375) + ([hashedone](https://github.com/hashedone)) +- cw20-merkle-airdrop: change hashing to sha256 [\#374](https://github.com/CosmWasm/cw-plus/pull/374) + ([orkunkl](https://github.com/orkunkl)) +- Responses validation in multi-test [\#373](https://github.com/CosmWasm/cw-plus/pull/373) + ([hashedone](https://github.com/hashedone)) - Cw20 logo spec [\#370](https://github.com/CosmWasm/cw-plus/pull/370) ([ethanfrey](https://github.com/ethanfrey)) -- Properly handling data in submessages in multi-test [\#369](https://github.com/CosmWasm/cw-plus/pull/369) ([hashedone](https://github.com/hashedone)) -- Abstracting API out of tests internals so it is clearly owned by `App` [\#368](https://github.com/CosmWasm/cw-plus/pull/368) ([hashedone](https://github.com/hashedone)) -- Storage plus doc correction [\#367](https://github.com/CosmWasm/cw-plus/pull/367) ([hashedone](https://github.com/hashedone)) -- Multitest migrate support [\#366](https://github.com/CosmWasm/cw-plus/pull/366) ([ethanfrey](https://github.com/ethanfrey)) -- Reorganizations of contracts in `multi-test::test_utils` [\#365](https://github.com/CosmWasm/cw-plus/pull/365) ([hashedone](https://github.com/hashedone)) -- Implement cw20-merkle-airdrop [\#364](https://github.com/CosmWasm/cw-plus/pull/364) ([orkunkl](https://github.com/orkunkl)) -- Testing sent founds visibility in multi-test [\#363](https://github.com/CosmWasm/cw-plus/pull/363) ([hashedone](https://github.com/hashedone)) +- Properly handling data in submessages in multi-test [\#369](https://github.com/CosmWasm/cw-plus/pull/369) + ([hashedone](https://github.com/hashedone)) +- Abstracting API out of tests internals so it is clearly owned by `App` + [\#368](https://github.com/CosmWasm/cw-plus/pull/368) ([hashedone](https://github.com/hashedone)) +- Storage plus doc correction [\#367](https://github.com/CosmWasm/cw-plus/pull/367) + ([hashedone](https://github.com/hashedone)) +- Multitest migrate support [\#366](https://github.com/CosmWasm/cw-plus/pull/366) + ([ethanfrey](https://github.com/ethanfrey)) +- Reorganizations of contracts in `multi-test::test_utils` [\#365](https://github.com/CosmWasm/cw-plus/pull/365) + ([hashedone](https://github.com/hashedone)) +- Implement cw20-merkle-airdrop [\#364](https://github.com/CosmWasm/cw-plus/pull/364) + ([orkunkl](https://github.com/orkunkl)) +- Testing sent founds visibility in multi-test [\#363](https://github.com/CosmWasm/cw-plus/pull/363) + ([hashedone](https://github.com/hashedone)) ## [v0.8.0-rc1](https://github.com/CosmWasm/cw-plus/tree/v0.8.0-rc1) (2021-07-29) @@ -776,25 +1027,37 @@ - storage-plus: Need better docs and examples for IndexedMap [\#327](https://github.com/CosmWasm/cw-plus/issues/327) - Improve `PkOwned` usability through `From` / `Into` [\#234](https://github.com/CosmWasm/cw-plus/issues/234) - Add ContractAddr generic helper [\#153](https://github.com/CosmWasm/cw-plus/issues/153) -- Brainstorm: cw-storage-plus support when key can be derived from stored object [\#120](https://github.com/CosmWasm/cw-plus/issues/120) +- Brainstorm: cw-storage-plus support when key can be derived from stored object + [\#120](https://github.com/CosmWasm/cw-plus/issues/120) **Merged pull requests:** -- Extend `ContractData` in multi-test [\#360](https://github.com/CosmWasm/cw-plus/pull/360) ([hashedone](https://github.com/hashedone)) -- Add transactional helper [\#357](https://github.com/CosmWasm/cw-plus/pull/357) ([ethanfrey](https://github.com/ethanfrey)) -- Implemented expiration for cw1-subkeys contract [\#356](https://github.com/CosmWasm/cw-plus/pull/356) ([hashedone](https://github.com/hashedone)) -- Clarify how cw20 minting is supposed to work [\#355](https://github.com/CosmWasm/cw-plus/pull/355) ([ethanfrey](https://github.com/ethanfrey)) -- Permission bugs corrected in cw1-subkeys [\#354](https://github.com/CosmWasm/cw-plus/pull/354) ([hashedone](https://github.com/hashedone)) +- Extend `ContractData` in multi-test [\#360](https://github.com/CosmWasm/cw-plus/pull/360) + ([hashedone](https://github.com/hashedone)) +- Add transactional helper [\#357](https://github.com/CosmWasm/cw-plus/pull/357) + ([ethanfrey](https://github.com/ethanfrey)) +- Implemented expiration for cw1-subkeys contract [\#356](https://github.com/CosmWasm/cw-plus/pull/356) + ([hashedone](https://github.com/hashedone)) +- Clarify how cw20 minting is supposed to work [\#355](https://github.com/CosmWasm/cw-plus/pull/355) + ([ethanfrey](https://github.com/ethanfrey)) +- Permission bugs corrected in cw1-subkeys [\#354](https://github.com/CosmWasm/cw-plus/pull/354) + ([hashedone](https://github.com/hashedone)) - Deprecate pks [\#345](https://github.com/CosmWasm/cw-plus/pull/345) ([maurolacy](https://github.com/maurolacy)) -- Refactor of cw1-whitelist unit tests [\#343](https://github.com/CosmWasm/cw-plus/pull/343) ([hashedone](https://github.com/hashedone)) -- Cw721 token indexes refactor [\#342](https://github.com/CosmWasm/cw-plus/pull/342) ([maurolacy](https://github.com/maurolacy)) +- Refactor of cw1-whitelist unit tests [\#343](https://github.com/CosmWasm/cw-plus/pull/343) + ([hashedone](https://github.com/hashedone)) +- Cw721 token indexes refactor [\#342](https://github.com/CosmWasm/cw-plus/pull/342) + ([maurolacy](https://github.com/maurolacy)) - Indexed map docs [\#340](https://github.com/CosmWasm/cw-plus/pull/340) ([maurolacy](https://github.com/maurolacy)) - Cosmwasm 0.16 [\#338](https://github.com/CosmWasm/cw-plus/pull/338) ([uint](https://github.com/uint)) -- Multitest bank events [\#337](https://github.com/CosmWasm/cw-plus/pull/337) ([ethanfrey](https://github.com/ethanfrey)) -- Fix clippy +1.53.0 warnings [\#336](https://github.com/CosmWasm/cw-plus/pull/336) ([maurolacy](https://github.com/maurolacy)) -- Simplify multitest storage [\#335](https://github.com/CosmWasm/cw-plus/pull/335) ([ethanfrey](https://github.com/ethanfrey)) +- Multitest bank events [\#337](https://github.com/CosmWasm/cw-plus/pull/337) + ([ethanfrey](https://github.com/ethanfrey)) +- Fix clippy +1.53.0 warnings [\#336](https://github.com/CosmWasm/cw-plus/pull/336) + ([maurolacy](https://github.com/maurolacy)) +- Simplify multitest storage [\#335](https://github.com/CosmWasm/cw-plus/pull/335) + ([ethanfrey](https://github.com/ethanfrey)) - Contract builders [\#334](https://github.com/CosmWasm/cw-plus/pull/334) ([ethanfrey](https://github.com/ethanfrey)) -- Update to cw schema 0.15.0 [\#332](https://github.com/CosmWasm/cw-plus/pull/332) ([maurolacy](https://github.com/maurolacy)) +- Update to cw schema 0.15.0 [\#332](https://github.com/CosmWasm/cw-plus/pull/332) + ([maurolacy](https://github.com/maurolacy)) ## [v0.7.0](https://github.com/CosmWasm/cw-plus/tree/v0.7.0) (2021-07-14) @@ -804,7 +1067,7 @@ - multi-test: Proper protobuf-encoded data for init [\#330](https://github.com/CosmWasm/cw-plus/issues/330) - Proper event/data handling on reply in multitest [\#326](https://github.com/CosmWasm/cw-plus/issues/326) -- Messages differ for cw20 & cw20\_base [\#320](https://github.com/CosmWasm/cw-plus/issues/320) +- Messages differ for cw20 & cw20_base [\#320](https://github.com/CosmWasm/cw-plus/issues/320) - Upgrade cw20-staking to cw 15 [\#312](https://github.com/CosmWasm/cw-plus/issues/312) - Uprade cw20-ics20 to cw 0.15 [\#311](https://github.com/CosmWasm/cw-plus/issues/311) - Upgrade cw20-escrow to 0.15 [\#309](https://github.com/CosmWasm/cw-plus/issues/309) @@ -821,25 +1084,41 @@ **Merged pull requests:** -- Use prost to create and parse proper InstantiateData [\#331](https://github.com/CosmWasm/cw-plus/pull/331) ([ethanfrey](https://github.com/ethanfrey)) +- Use prost to create and parse proper InstantiateData [\#331](https://github.com/CosmWasm/cw-plus/pull/331) + ([ethanfrey](https://github.com/ethanfrey)) - Reorg submessage [\#328](https://github.com/CosmWasm/cw-plus/pull/328) ([ethanfrey](https://github.com/ethanfrey)) - Cleanup multitest [\#324](https://github.com/CosmWasm/cw-plus/pull/324) ([ethanfrey](https://github.com/ethanfrey)) -- Support submessages in multitest [\#323](https://github.com/CosmWasm/cw-plus/pull/323) ([ethanfrey](https://github.com/ethanfrey)) -- Add has to Path and Map [\#322](https://github.com/CosmWasm/cw-plus/pull/322) ([ethanfrey](https://github.com/ethanfrey)) -- Make receiver msg non-optional in cw20 contracts [\#321](https://github.com/CosmWasm/cw-plus/pull/321) ([ethanfrey](https://github.com/ethanfrey)) -- Migrate contracts to 0.15.0 [\#318](https://github.com/CosmWasm/cw-plus/pull/318) ([orkunkl](https://github.com/orkunkl)) -- Update remaining contracts to cosmwasm 0.15, fix problems [\#317](https://github.com/CosmWasm/cw-plus/pull/317) ([uint](https://github.com/uint)) -- fix address range functions [\#316](https://github.com/CosmWasm/cw-plus/pull/316) ([pronvis](https://github.com/pronvis)) -- Upgrade cw3 contracts and `cw4-group` [\#315](https://github.com/CosmWasm/cw-plus/pull/315) ([uint](https://github.com/uint)) -- cw1155-base: upgrade cosmwasm-std to 0.15 [\#314](https://github.com/CosmWasm/cw-plus/pull/314) ([uint](https://github.com/uint)) -- cw20-staking: Upgrade cw 0.15 [\#313](https://github.com/CosmWasm/cw-plus/pull/313) ([orkunkl](https://github.com/orkunkl)) -- cw20-escrow: Upgrade to 0.15 [\#310](https://github.com/CosmWasm/cw-plus/pull/310) ([orkunkl](https://github.com/orkunkl)) -- cw20-bonding: Upgrade to 0.15 [\#308](https://github.com/CosmWasm/cw-plus/pull/308) ([orkunkl](https://github.com/orkunkl)) -- Update package schemas; fix linting errors [\#306](https://github.com/CosmWasm/cw-plus/pull/306) ([orkunkl](https://github.com/orkunkl)) -- cw20-base: Upgrade to cw 0.15 [\#304](https://github.com/CosmWasm/cw-plus/pull/304) ([orkunkl](https://github.com/orkunkl)) +- Support submessages in multitest [\#323](https://github.com/CosmWasm/cw-plus/pull/323) + ([ethanfrey](https://github.com/ethanfrey)) +- Add has to Path and Map [\#322](https://github.com/CosmWasm/cw-plus/pull/322) + ([ethanfrey](https://github.com/ethanfrey)) +- Make receiver msg non-optional in cw20 contracts [\#321](https://github.com/CosmWasm/cw-plus/pull/321) + ([ethanfrey](https://github.com/ethanfrey)) +- Migrate contracts to 0.15.0 [\#318](https://github.com/CosmWasm/cw-plus/pull/318) + ([orkunkl](https://github.com/orkunkl)) +- Update remaining contracts to cosmwasm 0.15, fix problems [\#317](https://github.com/CosmWasm/cw-plus/pull/317) + ([uint](https://github.com/uint)) +- fix address range functions [\#316](https://github.com/CosmWasm/cw-plus/pull/316) + ([pronvis](https://github.com/pronvis)) +- Upgrade cw3 contracts and `cw4-group` [\#315](https://github.com/CosmWasm/cw-plus/pull/315) + ([uint](https://github.com/uint)) +- cw1155-base: upgrade cosmwasm-std to 0.15 [\#314](https://github.com/CosmWasm/cw-plus/pull/314) + ([uint](https://github.com/uint)) +- cw20-staking: Upgrade cw 0.15 [\#313](https://github.com/CosmWasm/cw-plus/pull/313) + ([orkunkl](https://github.com/orkunkl)) +- cw20-escrow: Upgrade to 0.15 [\#310](https://github.com/CosmWasm/cw-plus/pull/310) + ([orkunkl](https://github.com/orkunkl)) +- cw20-bonding: Upgrade to 0.15 [\#308](https://github.com/CosmWasm/cw-plus/pull/308) + ([orkunkl](https://github.com/orkunkl)) +- Update package schemas; fix linting errors [\#306](https://github.com/CosmWasm/cw-plus/pull/306) + ([orkunkl](https://github.com/orkunkl)) +- cw20-base: Upgrade to cw 0.15 [\#304](https://github.com/CosmWasm/cw-plus/pull/304) + ([orkunkl](https://github.com/orkunkl)) - Upgrade cw1 contracts [\#303](https://github.com/CosmWasm/cw-plus/pull/303) ([uint](https://github.com/uint)) -- Upgrade packages to cosmwasm 0.15.0 [\#301](https://github.com/CosmWasm/cw-plus/pull/301) ([uint](https://github.com/uint)) -- cw20-base: upgrade helper.ts to cosmjs 0.25 [\#248](https://github.com/CosmWasm/cw-plus/pull/248) ([orkunkl](https://github.com/orkunkl)) +- Upgrade packages to cosmwasm 0.15.0 [\#301](https://github.com/CosmWasm/cw-plus/pull/301) + ([uint](https://github.com/uint)) +- cw20-base: upgrade helper.ts to cosmjs 0.25 [\#248](https://github.com/CosmWasm/cw-plus/pull/248) + ([orkunkl](https://github.com/orkunkl)) ## [v0.6.2](https://github.com/CosmWasm/cw-plus/tree/v0.6.2) (2021-06-23) @@ -847,8 +1126,10 @@ **Merged pull requests:** -- Extend the allowed names and symbols for cw20-base [\#299](https://github.com/CosmWasm/cw-plus/pull/299) ([ethanfrey](https://github.com/ethanfrey)) -- Implement PrimaryKey and Prefixer for String [\#294](https://github.com/CosmWasm/cw-plus/pull/294) ([ethanfrey](https://github.com/ethanfrey)) +- Extend the allowed names and symbols for cw20-base [\#299](https://github.com/CosmWasm/cw-plus/pull/299) + ([ethanfrey](https://github.com/ethanfrey)) +- Implement PrimaryKey and Prefixer for String [\#294](https://github.com/CosmWasm/cw-plus/pull/294) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.6.1](https://github.com/CosmWasm/cw-plus/tree/v0.6.1) (2021-05-19) @@ -860,7 +1141,8 @@ **Merged pull requests:** -- Expose contract components [\#293](https://github.com/CosmWasm/cw-plus/pull/293) ([orkunkl](https://github.com/orkunkl)) +- Expose contract components [\#293](https://github.com/CosmWasm/cw-plus/pull/293) + ([orkunkl](https://github.com/orkunkl)) ## [v0.6.0](https://github.com/CosmWasm/cw-plus/tree/v0.6.0) (2021-05-03) @@ -875,10 +1157,13 @@ **Merged pull requests:** -- Clarify index\_key\(\) range\(\) vs prefix\(\) behaviour [\#291](https://github.com/CosmWasm/cw-plus/pull/291) ([maurolacy](https://github.com/maurolacy)) +- Clarify index_key\(\) range\(\) vs prefix\(\) behaviour [\#291](https://github.com/CosmWasm/cw-plus/pull/291) + ([maurolacy](https://github.com/maurolacy)) - Pkowned to vec u8 [\#290](https://github.com/CosmWasm/cw-plus/pull/290) ([maurolacy](https://github.com/maurolacy)) -- Update to CosmWasm v0.14.0 [\#289](https://github.com/CosmWasm/cw-plus/pull/289) ([ethanfrey](https://github.com/ethanfrey)) -- Primary key / index key helpers [\#288](https://github.com/CosmWasm/cw-plus/pull/288) ([maurolacy](https://github.com/maurolacy)) +- Update to CosmWasm v0.14.0 [\#289](https://github.com/CosmWasm/cw-plus/pull/289) + ([ethanfrey](https://github.com/ethanfrey)) +- Primary key / index key helpers [\#288](https://github.com/CosmWasm/cw-plus/pull/288) + ([maurolacy](https://github.com/maurolacy)) ## [v0.6.0-beta3](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-beta3) (2021-04-28) @@ -888,18 +1173,24 @@ - Make message required in Cw20ReceiveMsg [\#283](https://github.com/CosmWasm/cw-plus/issues/283) - `Sudo` over no `new_with_sudo` contract wrapper error message [\#278](https://github.com/CosmWasm/cw-plus/issues/278) -- build\_and\_upload\_contract CI job fails [\#273](https://github.com/CosmWasm/cw-plus/issues/273) +- build_and_upload_contract CI job fails [\#273](https://github.com/CosmWasm/cw-plus/issues/273) - Add cw20 support to token-weighted group [\#143](https://github.com/CosmWasm/cw-plus/issues/143) **Merged pull requests:** - Cosmwasm beta5 [\#287](https://github.com/CosmWasm/cw-plus/pull/287) ([ethanfrey](https://github.com/ethanfrey)) -- Cw20ReceiveMsg msg field [\#286](https://github.com/CosmWasm/cw-plus/pull/286) ([maurolacy](https://github.com/maurolacy)) -- Fix ci contract build [\#285](https://github.com/CosmWasm/cw-plus/pull/285) ([ethanfrey](https://github.com/ethanfrey)) -- Use Cw20 token in cw4-stake [\#282](https://github.com/CosmWasm/cw-plus/pull/282) ([ethanfrey](https://github.com/ethanfrey)) -- Avoid the need for Any type by using Empty as message type and String as error type [\#281](https://github.com/CosmWasm/cw-plus/pull/281) ([webmaster128](https://github.com/webmaster128)) -- Update to 0.14.0 beta4 [\#280](https://github.com/CosmWasm/cw-plus/pull/280) ([maurolacy](https://github.com/maurolacy)) -- Better error message with missing sudo \(no parse error\) [\#279](https://github.com/CosmWasm/cw-plus/pull/279) ([ethanfrey](https://github.com/ethanfrey)) +- Cw20ReceiveMsg msg field [\#286](https://github.com/CosmWasm/cw-plus/pull/286) + ([maurolacy](https://github.com/maurolacy)) +- Fix ci contract build [\#285](https://github.com/CosmWasm/cw-plus/pull/285) + ([ethanfrey](https://github.com/ethanfrey)) +- Use Cw20 token in cw4-stake [\#282](https://github.com/CosmWasm/cw-plus/pull/282) + ([ethanfrey](https://github.com/ethanfrey)) +- Avoid the need for Any type by using Empty as message type and String as error type + [\#281](https://github.com/CosmWasm/cw-plus/pull/281) ([webmaster128](https://github.com/webmaster128)) +- Update to 0.14.0 beta4 [\#280](https://github.com/CosmWasm/cw-plus/pull/280) + ([maurolacy](https://github.com/maurolacy)) +- Better error message with missing sudo \(no parse error\) [\#279](https://github.com/CosmWasm/cw-plus/pull/279) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.6.0-beta2](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-beta2) (2021-04-19) @@ -911,9 +1202,11 @@ **Merged pull requests:** -- Indexed snapshot. Expose primary methods [\#275](https://github.com/CosmWasm/cw-plus/pull/275) ([maurolacy](https://github.com/maurolacy)) +- Indexed snapshot. Expose primary methods [\#275](https://github.com/CosmWasm/cw-plus/pull/275) + ([maurolacy](https://github.com/maurolacy)) - Indexed snapshot map [\#271](https://github.com/CosmWasm/cw-plus/pull/271) ([maurolacy](https://github.com/maurolacy)) -- Run clippy on test code [\#270](https://github.com/CosmWasm/cw-plus/pull/270) ([webmaster128](https://github.com/webmaster128)) +- Run clippy on test code [\#270](https://github.com/CosmWasm/cw-plus/pull/270) + ([webmaster128](https://github.com/webmaster128)) ## [v0.6.0-beta1](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-beta1) (2021-04-13) @@ -926,11 +1219,15 @@ **Merged pull requests:** -- Bump dependency to cosmasm v0.14.0-beta3 [\#269](https://github.com/CosmWasm/cw-plus/pull/269) ([ethanfrey](https://github.com/ethanfrey)) -- Remove unused PrimaryKey::parse\_key [\#267](https://github.com/CosmWasm/cw-plus/pull/267) ([webmaster128](https://github.com/webmaster128)) -- Use workspace-optimizer:0.11.0 [\#262](https://github.com/CosmWasm/cw-plus/pull/262) ([webmaster128](https://github.com/webmaster128)) +- Bump dependency to cosmasm v0.14.0-beta3 [\#269](https://github.com/CosmWasm/cw-plus/pull/269) + ([ethanfrey](https://github.com/ethanfrey)) +- Remove unused PrimaryKey::parse_key [\#267](https://github.com/CosmWasm/cw-plus/pull/267) + ([webmaster128](https://github.com/webmaster128)) +- Use workspace-optimizer:0.11.0 [\#262](https://github.com/CosmWasm/cw-plus/pull/262) + ([webmaster128](https://github.com/webmaster128)) - Update cosmwasm-std [\#260](https://github.com/CosmWasm/cw-plus/pull/260) ([yihuang](https://github.com/yihuang)) -- implement demo cw1155 contract [\#251](https://github.com/CosmWasm/cw-plus/pull/251) ([yihuang](https://github.com/yihuang)) +- implement demo cw1155 contract [\#251](https://github.com/CosmWasm/cw-plus/pull/251) + ([yihuang](https://github.com/yihuang)) ## [v0.6.0-alpha3](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-alpha3) (2021-04-01) @@ -938,7 +1235,8 @@ **Merged pull requests:** -- More multitest improvements [\#258](https://github.com/CosmWasm/cw-plus/pull/258) ([ethanfrey](https://github.com/ethanfrey)) +- More multitest improvements [\#258](https://github.com/CosmWasm/cw-plus/pull/258) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.6.0-alpha2](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-alpha2) (2021-04-01) @@ -946,19 +1244,22 @@ **Closed issues:** -- Re-enable field\_reassign\_with\_default [\#252](https://github.com/CosmWasm/cw-plus/issues/252) +- Re-enable field_reassign_with_default [\#252](https://github.com/CosmWasm/cw-plus/issues/252) - No equivalent of ERC1155 standard [\#246](https://github.com/CosmWasm/cw-plus/issues/246) - Rename HandleMsg to ExecuteMsg [\#236](https://github.com/CosmWasm/cw-plus/issues/236) -- Use \#\[entry\_point\] macro in contracts [\#230](https://github.com/CosmWasm/cw-plus/issues/230) +- Use \#\[entry_point\] macro in contracts [\#230](https://github.com/CosmWasm/cw-plus/issues/230) - Support PartialEq on error [\#179](https://github.com/CosmWasm/cw-plus/issues/179) **Merged pull requests:** - Enhance multi test [\#257](https://github.com/CosmWasm/cw-plus/pull/257) ([ethanfrey](https://github.com/ethanfrey)) -- Update to Rust v1.51.0 [\#254](https://github.com/CosmWasm/cw-plus/pull/254) ([maurolacy](https://github.com/maurolacy)) +- Update to Rust v1.51.0 [\#254](https://github.com/CosmWasm/cw-plus/pull/254) + ([maurolacy](https://github.com/maurolacy)) - PartialEq for errors [\#253](https://github.com/CosmWasm/cw-plus/pull/253) ([maurolacy](https://github.com/maurolacy)) -- Handle msg to execute msg [\#250](https://github.com/CosmWasm/cw-plus/pull/250) ([maurolacy](https://github.com/maurolacy)) -- Migrate to entry\_point macro [\#249](https://github.com/CosmWasm/cw-plus/pull/249) ([maurolacy](https://github.com/maurolacy)) +- Handle msg to execute msg [\#250](https://github.com/CosmWasm/cw-plus/pull/250) + ([maurolacy](https://github.com/maurolacy)) +- Migrate to entry_point macro [\#249](https://github.com/CosmWasm/cw-plus/pull/249) + ([maurolacy](https://github.com/maurolacy)) - Add cw1155 specification [\#247](https://github.com/CosmWasm/cw-plus/pull/247) ([yihuang](https://github.com/yihuang)) ## [v0.6.0-alpha1](https://github.com/CosmWasm/cw-plus/tree/v0.6.0-alpha1) (2021-03-12) @@ -972,30 +1273,42 @@ **Closed issues:** - Update to CosmWasm v0.14.0-beta1 [\#242](https://github.com/CosmWasm/cw-plus/issues/242) -- Support life-timed references in `UniqueIndex` and `MultiIndex` keys [\#233](https://github.com/CosmWasm/cw-plus/issues/233) +- Support life-timed references in `UniqueIndex` and `MultiIndex` keys + [\#233](https://github.com/CosmWasm/cw-plus/issues/233) - Write cw20-ics20 ibc enabled contract [\#231](https://github.com/CosmWasm/cw-plus/issues/231) - Upgrade to CosmWasm v0.14.0 [\#229](https://github.com/CosmWasm/cw-plus/issues/229) - Fix / remove cw20-bonding floating point instructions [\#227](https://github.com/CosmWasm/cw-plus/issues/227) - Add cw20-ics20 contract [\#226](https://github.com/CosmWasm/cw-plus/issues/226) - Upgrade to CosmWasm 0.14 [\#225](https://github.com/CosmWasm/cw-plus/issues/225) -- Use entry\_point macro for contract entry-points [\#224](https://github.com/CosmWasm/cw-plus/issues/224) +- Use entry_point macro for contract entry-points [\#224](https://github.com/CosmWasm/cw-plus/issues/224) - Upgrade Contracts to storage-plus [\#203](https://github.com/CosmWasm/cw-plus/issues/203) - Support composite keys on secondary indexes \(multi-index\) [\#163](https://github.com/CosmWasm/cw-plus/issues/163) **Merged pull requests:** - Fix ics20 denom [\#244](https://github.com/CosmWasm/cw-plus/pull/244) ([ethanfrey](https://github.com/ethanfrey)) -- Update to 0.14.0 beta1 [\#243](https://github.com/CosmWasm/cw-plus/pull/243) ([maurolacy](https://github.com/maurolacy)) -- Upgrade cw1 to storage plus [\#241](https://github.com/CosmWasm/cw-plus/pull/241) ([ethanfrey](https://github.com/ethanfrey)) -- Contract sanity checking [\#240](https://github.com/CosmWasm/cw-plus/pull/240) ([maurolacy](https://github.com/maurolacy)) -- Converting cw20-\* contracts to use storage-plus [\#239](https://github.com/CosmWasm/cw-plus/pull/239) ([ethanfrey](https://github.com/ethanfrey)) -- Create Contract to send cw20 tokens over ics20 [\#238](https://github.com/CosmWasm/cw-plus/pull/238) ([ethanfrey](https://github.com/ethanfrey)) -- Cw20 bonding deterministic [\#237](https://github.com/CosmWasm/cw-plus/pull/237) ([maurolacy](https://github.com/maurolacy)) -- Upgrade to 0.14.0 alpha2 [\#235](https://github.com/CosmWasm/cw-plus/pull/235) ([maurolacy](https://github.com/maurolacy)) -- cw3-fixed-multisig: write cw20 multi-contract mint test [\#223](https://github.com/CosmWasm/cw-plus/pull/223) ([orkunkl](https://github.com/orkunkl)) -- Document using tarpaulin [\#222](https://github.com/CosmWasm/cw-plus/pull/222) ([ethanfrey](https://github.com/ethanfrey)) -- Juggernaut/add cw20 support [\#221](https://github.com/CosmWasm/cw-plus/pull/221) ([juggernaut09](https://github.com/juggernaut09)) -- Multi index generic key [\#211](https://github.com/CosmWasm/cw-plus/pull/211) ([maurolacy](https://github.com/maurolacy)) +- Update to 0.14.0 beta1 [\#243](https://github.com/CosmWasm/cw-plus/pull/243) + ([maurolacy](https://github.com/maurolacy)) +- Upgrade cw1 to storage plus [\#241](https://github.com/CosmWasm/cw-plus/pull/241) + ([ethanfrey](https://github.com/ethanfrey)) +- Contract sanity checking [\#240](https://github.com/CosmWasm/cw-plus/pull/240) + ([maurolacy](https://github.com/maurolacy)) +- Converting cw20-\* contracts to use storage-plus [\#239](https://github.com/CosmWasm/cw-plus/pull/239) + ([ethanfrey](https://github.com/ethanfrey)) +- Create Contract to send cw20 tokens over ics20 [\#238](https://github.com/CosmWasm/cw-plus/pull/238) + ([ethanfrey](https://github.com/ethanfrey)) +- Cw20 bonding deterministic [\#237](https://github.com/CosmWasm/cw-plus/pull/237) + ([maurolacy](https://github.com/maurolacy)) +- Upgrade to 0.14.0 alpha2 [\#235](https://github.com/CosmWasm/cw-plus/pull/235) + ([maurolacy](https://github.com/maurolacy)) +- cw3-fixed-multisig: write cw20 multi-contract mint test [\#223](https://github.com/CosmWasm/cw-plus/pull/223) + ([orkunkl](https://github.com/orkunkl)) +- Document using tarpaulin [\#222](https://github.com/CosmWasm/cw-plus/pull/222) + ([ethanfrey](https://github.com/ethanfrey)) +- Juggernaut/add cw20 support [\#221](https://github.com/CosmWasm/cw-plus/pull/221) + ([juggernaut09](https://github.com/juggernaut09)) +- Multi index generic key [\#211](https://github.com/CosmWasm/cw-plus/pull/211) + ([maurolacy](https://github.com/maurolacy)) ## [v0.5.0](https://github.com/CosmWasm/cw-plus/tree/v0.5.0) (2021-01-19) @@ -1003,7 +1316,7 @@ **Closed issues:** -- Fix const\_item\_mutation warnings [\#217](https://github.com/CosmWasm/cw-plus/issues/217) +- Fix const_item_mutation warnings [\#217](https://github.com/CosmWasm/cw-plus/issues/217) - Add Prefixer sub-prefixes support [\#214](https://github.com/CosmWasm/cw-plus/issues/214) - Support composite keys on secondary indexes \(unique-index\) [\#209](https://github.com/CosmWasm/cw-plus/issues/209) - Update README, helpers [\#208](https://github.com/CosmWasm/cw-plus/issues/208) @@ -1011,14 +1324,19 @@ **Merged pull requests:** -- Update contracts and packages to cw 0.13.2 [\#220](https://github.com/CosmWasm/cw-plus/pull/220) ([orkunkl](https://github.com/orkunkl)) +- Update contracts and packages to cw 0.13.2 [\#220](https://github.com/CosmWasm/cw-plus/pull/220) + ([orkunkl](https://github.com/orkunkl)) - Payment helpers [\#219](https://github.com/CosmWasm/cw-plus/pull/219) ([ethanfrey](https://github.com/ethanfrey)) -- Make self constant in Item::update [\#218](https://github.com/CosmWasm/cw-plus/pull/218) ([webmaster128](https://github.com/webmaster128)) +- Make self constant in Item::update [\#218](https://github.com/CosmWasm/cw-plus/pull/218) + ([webmaster128](https://github.com/webmaster128)) - Prefixer sub prefix [\#215](https://github.com/CosmWasm/cw-plus/pull/215) ([maurolacy](https://github.com/maurolacy)) - Triple primary key 2 [\#213](https://github.com/CosmWasm/cw-plus/pull/213) ([maurolacy](https://github.com/maurolacy)) -- Update contract refs to v0.4.0 [\#212](https://github.com/CosmWasm/cw-plus/pull/212) ([maurolacy](https://github.com/maurolacy)) -- Implement PrimaryKey for generic \(T, U, V\) triplet [\#210](https://github.com/CosmWasm/cw-plus/pull/210) ([maurolacy](https://github.com/maurolacy)) -- Generalize UniqueIndex keys [\#207](https://github.com/CosmWasm/cw-plus/pull/207) ([maurolacy](https://github.com/maurolacy)) +- Update contract refs to v0.4.0 [\#212](https://github.com/CosmWasm/cw-plus/pull/212) + ([maurolacy](https://github.com/maurolacy)) +- Implement PrimaryKey for generic \(T, U, V\) triplet [\#210](https://github.com/CosmWasm/cw-plus/pull/210) + ([maurolacy](https://github.com/maurolacy)) +- Generalize UniqueIndex keys [\#207](https://github.com/CosmWasm/cw-plus/pull/207) + ([maurolacy](https://github.com/maurolacy)) ## [v0.4.0](https://github.com/CosmWasm/cw-plus/tree/v0.4.0) (2020-12-22) @@ -1053,39 +1371,62 @@ **Merged pull requests:** - Set events for cw4 [\#206](https://github.com/CosmWasm/cw-plus/pull/206) ([ethanfrey](https://github.com/ethanfrey)) -- Keep controllers' model private [\#204](https://github.com/CosmWasm/cw-plus/pull/204) ([ethanfrey](https://github.com/ethanfrey)) -- Fix cw1-subkeys helper.ts and point to heldernet [\#202](https://github.com/CosmWasm/cw-plus/pull/202) ([orkunkl](https://github.com/orkunkl)) -- Fix cw20-base helpers.ts and point to heldernet [\#201](https://github.com/CosmWasm/cw-plus/pull/201) ([orkunkl](https://github.com/orkunkl)) +- Keep controllers' model private [\#204](https://github.com/CosmWasm/cw-plus/pull/204) + ([ethanfrey](https://github.com/ethanfrey)) +- Fix cw1-subkeys helper.ts and point to heldernet [\#202](https://github.com/CosmWasm/cw-plus/pull/202) + ([orkunkl](https://github.com/orkunkl)) +- Fix cw20-base helpers.ts and point to heldernet [\#201](https://github.com/CosmWasm/cw-plus/pull/201) + ([orkunkl](https://github.com/orkunkl)) - Claims controller [\#200](https://github.com/CosmWasm/cw-plus/pull/200) ([ethanfrey](https://github.com/ethanfrey)) - Hooks controller [\#195](https://github.com/CosmWasm/cw-plus/pull/195) ([ethanfrey](https://github.com/ethanfrey)) -- Create Admin controller [\#194](https://github.com/CosmWasm/cw-plus/pull/194) ([ethanfrey](https://github.com/ethanfrey)) -- SnapshotMap properly tracks keys with multiple updates in one block [\#189](https://github.com/CosmWasm/cw-plus/pull/189) ([ethanfrey](https://github.com/ethanfrey)) +- Create Admin controller [\#194](https://github.com/CosmWasm/cw-plus/pull/194) + ([ethanfrey](https://github.com/ethanfrey)) +- SnapshotMap properly tracks keys with multiple updates in one block + [\#189](https://github.com/CosmWasm/cw-plus/pull/189) ([ethanfrey](https://github.com/ethanfrey)) - Update cw3 spec [\#188](https://github.com/CosmWasm/cw-plus/pull/188) ([ethanfrey](https://github.com/ethanfrey)) - Fix minor errors [\#186](https://github.com/CosmWasm/cw-plus/pull/186) ([ethanfrey](https://github.com/ethanfrey)) - Cw20 bonding curve [\#185](https://github.com/CosmWasm/cw-plus/pull/185) ([ethanfrey](https://github.com/ethanfrey)) -- Update all dependencies to 0.12.2 [\#184](https://github.com/CosmWasm/cw-plus/pull/184) ([ethanfrey](https://github.com/ethanfrey)) -- Add threshold to cw3 flex [\#180](https://github.com/CosmWasm/cw-plus/pull/180) ([ethanfrey](https://github.com/ethanfrey)) -- Replace byte slices by string slices in names and constructors [\#173](https://github.com/CosmWasm/cw-plus/pull/173) ([maurolacy](https://github.com/maurolacy)) -- Fix namespace macro test [\#169](https://github.com/CosmWasm/cw-plus/pull/169) ([maurolacy](https://github.com/maurolacy)) +- Update all dependencies to 0.12.2 [\#184](https://github.com/CosmWasm/cw-plus/pull/184) + ([ethanfrey](https://github.com/ethanfrey)) +- Add threshold to cw3 flex [\#180](https://github.com/CosmWasm/cw-plus/pull/180) + ([ethanfrey](https://github.com/ethanfrey)) +- Replace byte slices by string slices in names and constructors [\#173](https://github.com/CosmWasm/cw-plus/pull/173) + ([maurolacy](https://github.com/maurolacy)) +- Fix namespace macro test [\#169](https://github.com/CosmWasm/cw-plus/pull/169) + ([maurolacy](https://github.com/maurolacy)) - Token weighted group [\#167](https://github.com/CosmWasm/cw-plus/pull/167) ([ethanfrey](https://github.com/ethanfrey)) -- Snapshot cw4 \(take 2\) [\#166](https://github.com/CosmWasm/cw-plus/pull/166) ([ethanfrey](https://github.com/ethanfrey)) +- Snapshot cw4 \(take 2\) [\#166](https://github.com/CosmWasm/cw-plus/pull/166) + ([ethanfrey](https://github.com/ethanfrey)) - Snapshot module [\#164](https://github.com/CosmWasm/cw-plus/pull/164) ([ethanfrey](https://github.com/ethanfrey)) -- cw3-flex-multisig uses voting power from a snapshot of the block the proposal opened [\#160](https://github.com/CosmWasm/cw-plus/pull/160) ([ethanfrey](https://github.com/ethanfrey)) -- Weight 0 vs not member [\#159](https://github.com/CosmWasm/cw-plus/pull/159) ([maurolacy](https://github.com/maurolacy)) -- Weight 0 vs not member [\#158](https://github.com/CosmWasm/cw-plus/pull/158) ([maurolacy](https://github.com/maurolacy)) -- Close proposal on membership change [\#157](https://github.com/CosmWasm/cw-plus/pull/157) ([ethanfrey](https://github.com/ethanfrey)) +- cw3-flex-multisig uses voting power from a snapshot of the block the proposal opened + [\#160](https://github.com/CosmWasm/cw-plus/pull/160) ([ethanfrey](https://github.com/ethanfrey)) +- Weight 0 vs not member [\#159](https://github.com/CosmWasm/cw-plus/pull/159) + ([maurolacy](https://github.com/maurolacy)) +- Weight 0 vs not member [\#158](https://github.com/CosmWasm/cw-plus/pull/158) + ([maurolacy](https://github.com/maurolacy)) +- Close proposal on membership change [\#157](https://github.com/CosmWasm/cw-plus/pull/157) + ([ethanfrey](https://github.com/ethanfrey)) - Add cw4 hooks [\#156](https://github.com/CosmWasm/cw-plus/pull/156) ([ethanfrey](https://github.com/ethanfrey)) - Random Cleanup [\#155](https://github.com/CosmWasm/cw-plus/pull/155) ([ethanfrey](https://github.com/ethanfrey)) -- Update cosmwasm version to 0.12.0 [\#148](https://github.com/CosmWasm/cw-plus/pull/148) ([maurolacy](https://github.com/maurolacy)) -- Rename CanSend to CanExecute for generality [\#146](https://github.com/CosmWasm/cw-plus/pull/146) ([maurolacy](https://github.com/maurolacy)) -- Rename Router -\> App [\#144](https://github.com/CosmWasm/cw-plus/pull/144) ([ethanfrey](https://github.com/ethanfrey)) +- Update cosmwasm version to 0.12.0 [\#148](https://github.com/CosmWasm/cw-plus/pull/148) + ([maurolacy](https://github.com/maurolacy)) +- Rename CanSend to CanExecute for generality [\#146](https://github.com/CosmWasm/cw-plus/pull/146) + ([maurolacy](https://github.com/maurolacy)) +- Rename Router -\> App [\#144](https://github.com/CosmWasm/cw-plus/pull/144) + ([ethanfrey](https://github.com/ethanfrey)) - Multi test example [\#137](https://github.com/CosmWasm/cw-plus/pull/137) ([ethanfrey](https://github.com/ethanfrey)) -- Update to cosmwasm 0.12.0-alpha2 [\#136](https://github.com/CosmWasm/cw-plus/pull/136) ([ethanfrey](https://github.com/ethanfrey)) -- Router with rollbacks [\#134](https://github.com/CosmWasm/cw-plus/pull/134) ([ethanfrey](https://github.com/ethanfrey)) -- Initial version of helper.ts for CW721-base [\#131](https://github.com/CosmWasm/cw-plus/pull/131) ([volkrass](https://github.com/volkrass)) -- Document contract callback technique [\#152](https://github.com/CosmWasm/cw-plus/pull/152) ([ethanfrey](https://github.com/ethanfrey)) -- Separate multisig from group [\#150](https://github.com/CosmWasm/cw-plus/pull/150) ([ethanfrey](https://github.com/ethanfrey)) -- Sketch integration test framework [\#130](https://github.com/CosmWasm/cw-plus/pull/130) ([ethanfrey](https://github.com/ethanfrey)) +- Update to cosmwasm 0.12.0-alpha2 [\#136](https://github.com/CosmWasm/cw-plus/pull/136) + ([ethanfrey](https://github.com/ethanfrey)) +- Router with rollbacks [\#134](https://github.com/CosmWasm/cw-plus/pull/134) + ([ethanfrey](https://github.com/ethanfrey)) +- Initial version of helper.ts for CW721-base [\#131](https://github.com/CosmWasm/cw-plus/pull/131) + ([volkrass](https://github.com/volkrass)) +- Document contract callback technique [\#152](https://github.com/CosmWasm/cw-plus/pull/152) + ([ethanfrey](https://github.com/ethanfrey)) +- Separate multisig from group [\#150](https://github.com/CosmWasm/cw-plus/pull/150) + ([ethanfrey](https://github.com/ethanfrey)) +- Sketch integration test framework [\#130](https://github.com/CosmWasm/cw-plus/pull/130) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.3.2](https://github.com/CosmWasm/cw-plus/tree/v0.3.2) (2020-10-28) @@ -1093,7 +1434,8 @@ **Merged pull requests:** -- Fix SendNft in Cw721-base [\#132](https://github.com/CosmWasm/cw-plus/pull/132) ([ethanfrey](https://github.com/ethanfrey)) +- Fix SendNft in Cw721-base [\#132](https://github.com/CosmWasm/cw-plus/pull/132) + ([ethanfrey](https://github.com/ethanfrey)) - Define groups [\#129](https://github.com/CosmWasm/cw-plus/pull/129) ([ethanfrey](https://github.com/ethanfrey)) ## [v0.3.1](https://github.com/CosmWasm/cw-plus/tree/v0.3.1) (2020-10-16) @@ -1103,16 +1445,20 @@ **Closed issues:** - Update to CosmWasm 0.11.1 [\#127](https://github.com/CosmWasm/cw-plus/issues/127) -- Fix compiler warning \(const\_item\_mutation\) [\#123](https://github.com/CosmWasm/cw-plus/issues/123) +- Fix compiler warning \(const_item_mutation\) [\#123](https://github.com/CosmWasm/cw-plus/issues/123) - Implement TokensByOwner on base NFT contract [\#81](https://github.com/CosmWasm/cw-plus/issues/81) **Merged pull requests:** -- Bump cosmwasm version [\#128](https://github.com/CosmWasm/cw-plus/pull/128) ([ethanfrey](https://github.com/ethanfrey)) -- OwnedBound -\> Option\ [\#126](https://github.com/CosmWasm/cw-plus/pull/126) ([ethanfrey](https://github.com/ethanfrey)) +- Bump cosmwasm version [\#128](https://github.com/CosmWasm/cw-plus/pull/128) + ([ethanfrey](https://github.com/ethanfrey)) +- OwnedBound -\> Option\ [\#126](https://github.com/CosmWasm/cw-plus/pull/126) + ([ethanfrey](https://github.com/ethanfrey)) - Static index type [\#125](https://github.com/CosmWasm/cw-plus/pull/125) ([ethanfrey](https://github.com/ethanfrey)) -- Update Rust compiler [\#124](https://github.com/CosmWasm/cw-plus/pull/124) ([webmaster128](https://github.com/webmaster128)) -- Add TokensByOwner for cw721-base [\#122](https://github.com/CosmWasm/cw-plus/pull/122) ([ethanfrey](https://github.com/ethanfrey)) +- Update Rust compiler [\#124](https://github.com/CosmWasm/cw-plus/pull/124) + ([webmaster128](https://github.com/webmaster128)) +- Add TokensByOwner for cw721-base [\#122](https://github.com/CosmWasm/cw-plus/pull/122) + ([ethanfrey](https://github.com/ethanfrey)) - Secondary indexes [\#108](https://github.com/CosmWasm/cw-plus/pull/108) ([ethanfrey](https://github.com/ethanfrey)) ## [v0.3.0](https://github.com/CosmWasm/cw-plus/tree/v0.3.0) (2020-10-12) @@ -1122,19 +1468,25 @@ **Closed issues:** - Building contracts failed [\#117](https://github.com/CosmWasm/cw-plus/issues/117) -- Remove dependency between cw20\_escrow and cw20\_atomic\_swap [\#115](https://github.com/CosmWasm/cw-plus/issues/115) +- Remove dependency between cw20_escrow and cw20_atomic_swap [\#115](https://github.com/CosmWasm/cw-plus/issues/115) - Fix Claims handling in cw20-staking [\#110](https://github.com/CosmWasm/cw-plus/issues/110) - Migrate contracts to v0.11 [\#96](https://github.com/CosmWasm/cw-plus/issues/96) **Merged pull requests:** -- Fix workspace optimizer [\#121](https://github.com/CosmWasm/cw-plus/pull/121) ([ethanfrey](https://github.com/ethanfrey)) -- Migrate cw3-fixed-multisig [\#119](https://github.com/CosmWasm/cw-plus/pull/119) ([ethanfrey](https://github.com/ethanfrey)) -- Move shared Balance struct to cw20 [\#118](https://github.com/CosmWasm/cw-plus/pull/118) ([maurolacy](https://github.com/maurolacy)) -- Use Include/Exclude Bounds to define range searches [\#116](https://github.com/CosmWasm/cw-plus/pull/116) ([ethanfrey](https://github.com/ethanfrey)) -- Merge 0.2.x into master [\#114](https://github.com/CosmWasm/cw-plus/pull/114) ([ethanfrey](https://github.com/ethanfrey)) +- Fix workspace optimizer [\#121](https://github.com/CosmWasm/cw-plus/pull/121) + ([ethanfrey](https://github.com/ethanfrey)) +- Migrate cw3-fixed-multisig [\#119](https://github.com/CosmWasm/cw-plus/pull/119) + ([ethanfrey](https://github.com/ethanfrey)) +- Move shared Balance struct to cw20 [\#118](https://github.com/CosmWasm/cw-plus/pull/118) + ([maurolacy](https://github.com/maurolacy)) +- Use Include/Exclude Bounds to define range searches [\#116](https://github.com/CosmWasm/cw-plus/pull/116) + ([ethanfrey](https://github.com/ethanfrey)) +- Merge 0.2.x into master [\#114](https://github.com/CosmWasm/cw-plus/pull/114) + ([ethanfrey](https://github.com/ethanfrey)) - Migrate to v0.11.0 [\#113](https://github.com/CosmWasm/cw-plus/pull/113) ([ethanfrey](https://github.com/ethanfrey)) -- Finish v0.11 migration [\#111](https://github.com/CosmWasm/cw-plus/pull/111) ([ethanfrey](https://github.com/ethanfrey)) +- Finish v0.11 migration [\#111](https://github.com/CosmWasm/cw-plus/pull/111) + ([ethanfrey](https://github.com/ethanfrey)) - Use Maps for storage [\#109](https://github.com/CosmWasm/cw-plus/pull/109) ([ethanfrey](https://github.com/ethanfrey)) - Migrate to v0.11 2 [\#107](https://github.com/CosmWasm/cw-plus/pull/107) ([maurolacy](https://github.com/maurolacy)) - Migrate to v0.11 [\#104](https://github.com/CosmWasm/cw-plus/pull/104) ([maurolacy](https://github.com/maurolacy)) @@ -1145,12 +1497,14 @@ **Closed issues:** -- Migration to 0.11: errors of shared functions accross contracts [\#103](https://github.com/CosmWasm/cw-plus/issues/103) +- Migration to 0.11: errors of shared functions accross contracts + [\#103](https://github.com/CosmWasm/cw-plus/issues/103) - Look at serde\(flatten\) to simplify return value composition [\#57](https://github.com/CosmWasm/cw-plus/issues/57) **Merged pull requests:** -- Better staking claims [\#112](https://github.com/CosmWasm/cw-plus/pull/112) ([ethanfrey](https://github.com/ethanfrey)) +- Better staking claims [\#112](https://github.com/CosmWasm/cw-plus/pull/112) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.2.2](https://github.com/CosmWasm/cw-plus/tree/v0.2.2) (2020-09-30) @@ -1158,7 +1512,7 @@ **Closed issues:** -- calc\_range\_start to cw0 [\#101](https://github.com/CosmWasm/cw-plus/issues/101) +- calc_range_start to cw0 [\#101](https://github.com/CosmWasm/cw-plus/issues/101) - Avoid sending zero amount cw20 tokens [\#89](https://github.com/CosmWasm/cw-plus/issues/89) - Unify handling of native and cw20 coins in contracts [\#88](https://github.com/CosmWasm/cw-plus/issues/88) - Define cw3 spec for multisigs [\#79](https://github.com/CosmWasm/cw-plus/issues/79) @@ -1169,16 +1523,24 @@ **Merged pull requests:** - Fix calc range [\#102](https://github.com/CosmWasm/cw-plus/pull/102) ([ethanfrey](https://github.com/ethanfrey)) -- Fix CLI call command [\#100](https://github.com/CosmWasm/cw-plus/pull/100) ([webmaster128](https://github.com/webmaster128)) -- Implement cw721-base nft contract [\#97](https://github.com/CosmWasm/cw-plus/pull/97) ([ethanfrey](https://github.com/ethanfrey)) -- Unit tests for cw3-fixed-multisig [\#95](https://github.com/CosmWasm/cw-plus/pull/95) ([maurolacy](https://github.com/maurolacy)) -- Add zero amount checks / tests [\#94](https://github.com/CosmWasm/cw-plus/pull/94) ([maurolacy](https://github.com/maurolacy)) -- cw20-escrow refactoring: Unify handling of native and cw20 [\#92](https://github.com/CosmWasm/cw-plus/pull/92) ([maurolacy](https://github.com/maurolacy)) +- Fix CLI call command [\#100](https://github.com/CosmWasm/cw-plus/pull/100) + ([webmaster128](https://github.com/webmaster128)) +- Implement cw721-base nft contract [\#97](https://github.com/CosmWasm/cw-plus/pull/97) + ([ethanfrey](https://github.com/ethanfrey)) +- Unit tests for cw3-fixed-multisig [\#95](https://github.com/CosmWasm/cw-plus/pull/95) + ([maurolacy](https://github.com/maurolacy)) +- Add zero amount checks / tests [\#94](https://github.com/CosmWasm/cw-plus/pull/94) + ([maurolacy](https://github.com/maurolacy)) +- cw20-escrow refactoring: Unify handling of native and cw20 [\#92](https://github.com/CosmWasm/cw-plus/pull/92) + ([maurolacy](https://github.com/maurolacy)) - Cw3 fixed multisig [\#91](https://github.com/CosmWasm/cw-plus/pull/91) ([ethanfrey](https://github.com/ethanfrey)) - Cw3 spec [\#90](https://github.com/CosmWasm/cw-plus/pull/90) ([ethanfrey](https://github.com/ethanfrey)) -- Native balance refactoring [\#87](https://github.com/CosmWasm/cw-plus/pull/87) ([maurolacy](https://github.com/maurolacy)) -- Cw20 zero amount checks [\#86](https://github.com/CosmWasm/cw-plus/pull/86) ([maurolacy](https://github.com/maurolacy)) -- Update helpers source tags and builder info [\#85](https://github.com/CosmWasm/cw-plus/pull/85) ([orkunkl](https://github.com/orkunkl)) +- Native balance refactoring [\#87](https://github.com/CosmWasm/cw-plus/pull/87) + ([maurolacy](https://github.com/maurolacy)) +- Cw20 zero amount checks [\#86](https://github.com/CosmWasm/cw-plus/pull/86) + ([maurolacy](https://github.com/maurolacy)) +- Update helpers source tags and builder info [\#85](https://github.com/CosmWasm/cw-plus/pull/85) + ([orkunkl](https://github.com/orkunkl)) ## [v0.2.1](https://github.com/CosmWasm/cw-plus/tree/v0.2.1) (2020-09-10) @@ -1195,13 +1557,18 @@ **Merged pull requests:** -- Update workspace optimizer version to 0.10.3 [\#83](https://github.com/CosmWasm/cw-plus/pull/83) ([orkunkl](https://github.com/orkunkl)) -- cw1-subkeys: Point helper to smart contract version v0.2.1 [\#82](https://github.com/CosmWasm/cw-plus/pull/82) ([orkunkl](https://github.com/orkunkl)) +- Update workspace optimizer version to 0.10.3 [\#83](https://github.com/CosmWasm/cw-plus/pull/83) + ([orkunkl](https://github.com/orkunkl)) +- cw1-subkeys: Point helper to smart contract version v0.2.1 [\#82](https://github.com/CosmWasm/cw-plus/pull/82) + ([orkunkl](https://github.com/orkunkl)) - Cw20coin refactoring [\#78](https://github.com/CosmWasm/cw-plus/pull/78) ([maurolacy](https://github.com/maurolacy)) -- cw1-subkeys: Implement permission functionality [\#75](https://github.com/CosmWasm/cw-plus/pull/75) ([orkunkl](https://github.com/orkunkl)) +- cw1-subkeys: Implement permission functionality [\#75](https://github.com/CosmWasm/cw-plus/pull/75) + ([orkunkl](https://github.com/orkunkl)) - Cw20 atomic swaps [\#72](https://github.com/CosmWasm/cw-plus/pull/72) ([maurolacy](https://github.com/maurolacy)) -- Update contracts README \(workspace-optimizer\) [\#71](https://github.com/CosmWasm/cw-plus/pull/71) ([maurolacy](https://github.com/maurolacy)) -- Update with new wasm, new queries [\#70](https://github.com/CosmWasm/cw-plus/pull/70) ([ethanfrey](https://github.com/ethanfrey)) +- Update contracts README \(workspace-optimizer\) [\#71](https://github.com/CosmWasm/cw-plus/pull/71) + ([maurolacy](https://github.com/maurolacy)) +- Update with new wasm, new queries [\#70](https://github.com/CosmWasm/cw-plus/pull/70) + ([ethanfrey](https://github.com/ethanfrey)) - Subkeys details [\#68](https://github.com/CosmWasm/cw-plus/pull/68) ([maurolacy](https://github.com/maurolacy)) - Atomic swap [\#52](https://github.com/CosmWasm/cw-plus/pull/52) ([maurolacy](https://github.com/maurolacy)) @@ -1221,9 +1588,12 @@ - Cw20-base migration [\#67](https://github.com/CosmWasm/cw-plus/pull/67) ([ethanfrey](https://github.com/ethanfrey)) - Add readme [\#65](https://github.com/CosmWasm/cw-plus/pull/65) ([ethanfrey](https://github.com/ethanfrey)) - Cw20 base iterators [\#64](https://github.com/CosmWasm/cw-plus/pull/64) ([ethanfrey](https://github.com/ethanfrey)) -- workshop subkey PR [\#62](https://github.com/CosmWasm/cw-plus/pull/62) ([whalelephant](https://github.com/whalelephant)) -- Add cw20 functionality to the staking contract [\#60](https://github.com/CosmWasm/cw-plus/pull/60) ([ethanfrey](https://github.com/ethanfrey)) -- Add basic staking derivatives as CW20 token contracts [\#58](https://github.com/CosmWasm/cw-plus/pull/58) ([ethanfrey](https://github.com/ethanfrey)) +- workshop subkey PR [\#62](https://github.com/CosmWasm/cw-plus/pull/62) + ([whalelephant](https://github.com/whalelephant)) +- Add cw20 functionality to the staking contract [\#60](https://github.com/CosmWasm/cw-plus/pull/60) + ([ethanfrey](https://github.com/ethanfrey)) +- Add basic staking derivatives as CW20 token contracts [\#58](https://github.com/CosmWasm/cw-plus/pull/58) + ([ethanfrey](https://github.com/ethanfrey)) ## [workshop-pre-cw20-staking](https://github.com/CosmWasm/cw-plus/tree/workshop-pre-cw20-staking) (2020-08-26) @@ -1237,13 +1607,17 @@ **Merged pull requests:** -- Bump all CosmWasm dependencies to 0.10.1 [\#56](https://github.com/CosmWasm/cw-plus/pull/56) ([ethanfrey](https://github.com/ethanfrey)) -- Add new query to return all allowances on subkeys [\#54](https://github.com/CosmWasm/cw-plus/pull/54) ([ethanfrey](https://github.com/ethanfrey)) -- Add CanSend query to the cw1 spec [\#53](https://github.com/CosmWasm/cw-plus/pull/53) ([ethanfrey](https://github.com/ethanfrey)) +- Bump all CosmWasm dependencies to 0.10.1 [\#56](https://github.com/CosmWasm/cw-plus/pull/56) + ([ethanfrey](https://github.com/ethanfrey)) +- Add new query to return all allowances on subkeys [\#54](https://github.com/CosmWasm/cw-plus/pull/54) + ([ethanfrey](https://github.com/ethanfrey)) +- Add CanSend query to the cw1 spec [\#53](https://github.com/CosmWasm/cw-plus/pull/53) + ([ethanfrey](https://github.com/ethanfrey)) - Add Expration to cw0 [\#51](https://github.com/CosmWasm/cw-plus/pull/51) ([ethanfrey](https://github.com/ethanfrey)) - Nft 721 spec [\#50](https://github.com/CosmWasm/cw-plus/pull/50) ([ethanfrey](https://github.com/ethanfrey)) - Add Subkeys helper [\#49](https://github.com/CosmWasm/cw-plus/pull/49) ([ethanfrey](https://github.com/ethanfrey)) -- Add helpers to cw20-base [\#46](https://github.com/CosmWasm/cw-plus/pull/46) ([ethanfrey](https://github.com/ethanfrey)) +- Add helpers to cw20-base [\#46](https://github.com/CosmWasm/cw-plus/pull/46) + ([ethanfrey](https://github.com/ethanfrey)) ## [v0.1.1](https://github.com/CosmWasm/cw-plus/tree/v0.1.1) (2020-08-13) @@ -1259,7 +1633,8 @@ **Closed issues:** -- Use more unique names for store/queries \(not "Config" / "Meta"\) [\#37](https://github.com/CosmWasm/cw-plus/issues/37) +- Use more unique names for store/queries \(not "Config" / "Meta"\) + [\#37](https://github.com/CosmWasm/cw-plus/issues/37) - Convert all existing code to apache license [\#36](https://github.com/CosmWasm/cw-plus/issues/36) - Upgrade contracts to 0.10 [\#31](https://github.com/CosmWasm/cw-plus/issues/31) - Avoid linking contract into contract [\#30](https://github.com/CosmWasm/cw-plus/issues/30) @@ -1274,28 +1649,39 @@ **Merged pull requests:** -- Add migration info to contracts [\#45](https://github.com/CosmWasm/cw-plus/pull/45) ([ethanfrey](https://github.com/ethanfrey)) -- Add optimization config to all contracts in Cargo.toml [\#42](https://github.com/CosmWasm/cw-plus/pull/42) ([ethanfrey](https://github.com/ethanfrey)) +- Add migration info to contracts [\#45](https://github.com/CosmWasm/cw-plus/pull/45) + ([ethanfrey](https://github.com/ethanfrey)) +- Add optimization config to all contracts in Cargo.toml [\#42](https://github.com/CosmWasm/cw-plus/pull/42) + ([ethanfrey](https://github.com/ethanfrey)) - Agpl to apache [\#41](https://github.com/CosmWasm/cw-plus/pull/41) ([ethanfrey](https://github.com/ethanfrey)) - Unique singleton names [\#39](https://github.com/CosmWasm/cw-plus/pull/39) ([ethanfrey](https://github.com/ethanfrey)) - Cw2 migrate spec [\#34](https://github.com/CosmWasm/cw-plus/pull/34) ([ethanfrey](https://github.com/ethanfrey)) - Update to 0.10.0 final [\#33](https://github.com/CosmWasm/cw-plus/pull/33) ([maurolacy](https://github.com/maurolacy)) -- Enable contracts to import contracts [\#32](https://github.com/CosmWasm/cw-plus/pull/32) ([ethanfrey](https://github.com/ethanfrey)) -- Add deployment job to CI [\#29](https://github.com/CosmWasm/cw-plus/pull/29) ([webmaster128](https://github.com/webmaster128)) +- Enable contracts to import contracts [\#32](https://github.com/CosmWasm/cw-plus/pull/32) + ([ethanfrey](https://github.com/ethanfrey)) +- Add deployment job to CI [\#29](https://github.com/CosmWasm/cw-plus/pull/29) + ([webmaster128](https://github.com/webmaster128)) - Subkeys 2 [\#28](https://github.com/CosmWasm/cw-plus/pull/28) ([maurolacy](https://github.com/maurolacy)) - Update to 0.10 [\#25](https://github.com/CosmWasm/cw-plus/pull/25) ([maurolacy](https://github.com/maurolacy)) -- Implement subkeys as a cw1 contract [\#24](https://github.com/CosmWasm/cw-plus/pull/24) ([ethanfrey](https://github.com/ethanfrey)) -- Rename multisig to whitelist [\#23](https://github.com/CosmWasm/cw-plus/pull/23) ([ethanfrey](https://github.com/ethanfrey)) -- Add Cw1 for proxy contracts [\#22](https://github.com/CosmWasm/cw-plus/pull/22) ([ethanfrey](https://github.com/ethanfrey)) +- Implement subkeys as a cw1 contract [\#24](https://github.com/CosmWasm/cw-plus/pull/24) + ([ethanfrey](https://github.com/ethanfrey)) +- Rename multisig to whitelist [\#23](https://github.com/CosmWasm/cw-plus/pull/23) + ([ethanfrey](https://github.com/ethanfrey)) +- Add Cw1 for proxy contracts [\#22](https://github.com/CosmWasm/cw-plus/pull/22) + ([ethanfrey](https://github.com/ethanfrey)) - Cw20 allowances [\#21](https://github.com/CosmWasm/cw-plus/pull/21) ([ethanfrey](https://github.com/ethanfrey)) - Fix escrow DoS Attack [\#20](https://github.com/CosmWasm/cw-plus/pull/20) ([ethanfrey](https://github.com/ethanfrey)) - Cw20 base mintable [\#18](https://github.com/CosmWasm/cw-plus/pull/18) ([ethanfrey](https://github.com/ethanfrey)) - Cw20 escrow [\#16](https://github.com/CosmWasm/cw-plus/pull/16) ([ethanfrey](https://github.com/ethanfrey)) - Cleanup contract [\#14](https://github.com/CosmWasm/cw-plus/pull/14) ([ethanfrey](https://github.com/ethanfrey)) -- Create basic Cw20 contract \(reference\) [\#12](https://github.com/CosmWasm/cw-plus/pull/12) ([ethanfrey](https://github.com/ethanfrey)) -- Define all Message and Query types [\#11](https://github.com/CosmWasm/cw-plus/pull/11) ([ethanfrey](https://github.com/ethanfrey)) +- Create basic Cw20 contract \(reference\) [\#12](https://github.com/CosmWasm/cw-plus/pull/12) + ([ethanfrey](https://github.com/ethanfrey)) +- Define all Message and Query types [\#11](https://github.com/CosmWasm/cw-plus/pull/11) + ([ethanfrey](https://github.com/ethanfrey)) - Set up basic CI script [\#10](https://github.com/CosmWasm/cw-plus/pull/10) ([ethanfrey](https://github.com/ethanfrey)) +\* _This Changelog was automatically generated by +[github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)_ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From 499b01bd1088c3b9b360918701a7d606e5dca16e Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Fri, 22 Mar 2024 15:02:28 +0100 Subject: [PATCH 624/631] Upgraded MultiTest to version 2.0.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f9d1bd07..c592da276 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,9 +232,9 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "2.0.0-rc.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e83a1453fc6a9348a67a24ada22a5a2fae675305844bb85c2a436c930cffdd" +checksum = "b7b69c1ba533753a2c90e60f4c803f52ee80cf3ba183c3ca0645fd1796561951" dependencies = [ "anyhow", "bech32 0.11.0", diff --git a/Cargo.toml b/Cargo.toml index 91ecd244d..d6693b20f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ cosmwasm-schema = "2.0.0" cosmwasm-std = "2.0.0" cw2 = "2.0.0" cw-controllers = "2.0.0" -cw-multi-test = "2.0.0-rc.2" +cw-multi-test = "2.0.0" cw-storage-plus = "2.0.0" cw-utils = "2.0.0" schemars = "0.8.15" From d91c70ea53acf2ac694efa343f3697e7cd165534 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 26 Mar 2024 21:34:44 +0100 Subject: [PATCH 625/631] bump version to 2.0.0 --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c592da276..71fbc47d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,7 +276,7 @@ dependencies = [ [[package]] name = "cw1" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -286,7 +286,7 @@ dependencies = [ [[package]] name = "cw1-subkeys" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -304,7 +304,7 @@ dependencies = [ [[package]] name = "cw1-whitelist" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "anyhow", "assert_matches", @@ -338,7 +338,7 @@ dependencies = [ [[package]] name = "cw20" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -349,7 +349,7 @@ dependencies = [ [[package]] name = "cw20-base" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "cw20-ics20" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -384,7 +384,7 @@ dependencies = [ [[package]] name = "cw3" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -397,7 +397,7 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -416,7 +416,7 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -438,7 +438,7 @@ dependencies = [ [[package]] name = "cw4" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -466,7 +466,7 @@ dependencies = [ [[package]] name = "cw4-stake" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -532,7 +532,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "easy-addr" -version = "2.0.0-rc.0" +version = "2.0.0" dependencies = [ "cosmwasm-std", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index d6693b20f..5a0c6fb96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ members = ["packages/*", "contracts/*"] resolver = "2" [workspace.package] -version = "2.0.0-rc.0" +version = "2.0.0" [workspace.dependencies] cosmwasm-schema = "2.0.0" From 7cb79fb4e66b386fa64708f5612c101c835661b1 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 26 Mar 2024 21:51:05 +0100 Subject: [PATCH 626/631] CHANGELOG update --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76df00fb2..9182dc5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [v2.0.0](https://github.com/CosmWasm/cw-plus/tree/v2.0.0) (2024-03-26) + +[Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v2.0.0-rc.0...v2.0.0) + +**Merged pull requests:** + +- Upgraded MultiTest to version 2.0.0 [\#903](https://github.com/CosmWasm/cw-plus/pull/903) ([DariuszDepta](https://github.com/DariuszDepta)) +- Align all crates to the 2.0.0 framework [\#902](https://github.com/CosmWasm/cw-plus/pull/902) ([uint](https://github.com/uint)) + ## [v2.0.0-rc.0](https://github.com/CosmWasm/cw-plus/tree/v2.0.0-rc.0) (2024-03-20) [Full Changelog](https://github.com/CosmWasm/cw-plus/compare/v1.1.2...v2.0.0-rc.0) From 661ad84992cb6b5318cdd4bde215de63e835a2d8 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 27 Mar 2024 10:42:32 +0100 Subject: [PATCH 627/631] delete publish.sh --- scripts/publish.sh | 73 ---------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100755 scripts/publish.sh diff --git a/scripts/publish.sh b/scripts/publish.sh deleted file mode 100755 index c7b545c24..000000000 --- a/scripts/publish.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -set -o errexit -o nounset -o pipefail -command -v shellcheck >/dev/null && shellcheck "$0" - -function print_usage() { - echo "Usage: $0 [-h|--help]" - echo "Publishes crates to crates.io." -} - -if [ $# = 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ] ; } -then - print_usage - exit 1 -fi - -# These are imported by other packages -ALL_PACKAGES="cw1 cw3 cw4 cw20" - -# This is imported by cw3-fixed-multisig, which is imported by cw3-flex-multisig -# need to make a separate category to remove race conditions -CW20_BASE="cw20-base" -# these are imported by other contracts -BASE_CONTRACTS="cw1-whitelist cw4-group cw3-fixed-multisig " -ALL_CONTRACTS="cw1-subkeys cw3-flex-multisig cw4-stake cw20-ics20" - -SLEEP_TIME=30 - -for pack in $ALL_PACKAGES; do - ( - cd "packages/$pack" - echo "Publishing $pack" - cargo publish - ) -done - - -# wait for these to be processed on crates.io -echo "Waiting for publishing all packages" -sleep $SLEEP_TIME - -for cont in $CW20_BASE; do - ( - cd "contracts/$cont" - echo "Publishing $cont" - cargo publish - ) -done - -# wait for these to be processed on crates.io -echo "Waiting for publishing cw20 base" -sleep $SLEEP_TIME - -for cont in $BASE_CONTRACTS; do - ( - cd "contracts/$cont" - echo "Publishing $cont" - cargo publish - ) -done - -# wait for these to be processed on crates.io -echo "Waiting for publishing base contracts" -sleep $SLEEP_TIME - -for cont in $ALL_CONTRACTS; do - ( - cd "contracts/$cont" - echo "Publishing $cont" - cargo publish - ) -done - -echo "Everything is published!" From d75746beb7b96ca916aa84575844e89a513507e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:38:36 +0000 Subject: [PATCH 628/631] Bump cosmwasm-std from 2.0.0 to 2.0.2 Bumps [cosmwasm-std](https://github.com/CosmWasm/cosmwasm) from 2.0.0 to 2.0.2. - [Release notes](https://github.com/CosmWasm/cosmwasm/releases) - [Changelog](https://github.com/CosmWasm/cosmwasm/blob/v2.0.2/CHANGELOG.md) - [Commits](https://github.com/CosmWasm/cosmwasm/compare/v2.0.0...v2.0.2) --- updated-dependencies: - dependency-name: cosmwasm-std dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71fbc47d3..605d7c97b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,9 +105,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5fd9485d4f1f4330547a8a5aaf0958c68b4d620975ded2c15f2ed5c49e8e74" +checksum = "d8b08e6670ab9e13a1a8a9cfad8fdad48bf0aaf88a6e81f39f2d9b2fc79b1890" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -118,9 +118,9 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d692944045feabbf46c75e8f072024bb885a7742025e40d46913296fe9fbbd06" +checksum = "b8b0918fc1a24b2ee08142c8d99d03f4c8e6d74244bdb304dbb29c0dab8e77e9" dependencies = [ "syn 1.0.109", ] @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464f484b3f289935a41e374560c66c59a8f881aefc74742558e42008f1b0b7f3" +checksum = "88191bd0d4743613eb7a2f086acb0838404cb531bf658382effafc7ba91e8320" dependencies = [ "base64", "bech32 0.9.1", diff --git a/Cargo.toml b/Cargo.toml index 5a0c6fb96..179608252 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ version = "2.0.0" [workspace.dependencies] cosmwasm-schema = "2.0.0" -cosmwasm-std = "2.0.0" +cosmwasm-std = "2.0.2" cw2 = "2.0.0" cw-controllers = "2.0.0" cw-multi-test = "2.0.0" From 6d1eea2a357ed8a98c16e0a2cc2abd15e8e30905 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 14 Jun 2024 12:51:32 +0200 Subject: [PATCH 629/631] Upgrade optimizer --- .circleci/config.yml | 2 +- README.md | 6 +++--- scripts/optimizer.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 534f7ef77..d2a1884b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -506,7 +506,7 @@ jobs: - run: name: Build development contracts command: | - docker run --volumes-from with_code cosmwasm/workspace-optimizer:0.13.0 + docker run --volumes-from with_code cosmwasm/optimizer:0.16.0 docker cp with_code:/code/artifacts ./artifacts - run: name: Show data diff --git a/README.md b/README.md index 0e9cc5092..9b9a069ff 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ | cw4 | [![cw4 on crates.io](https://img.shields.io/crates/v/cw4.svg)](https://crates.io/crates/cw4) | [![Docs](https://docs.rs/cw4/badge.svg)](https://docs.rs/cw4) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20 | [![cw20 on crates.io](https://img.shields.io/crates/v/cw20.svg)](https://crates.io/crates/cw20) | [![Docs](https://docs.rs/cw20/badge.svg)](https://docs.rs/cw20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | - | Contracts | Download | Docs | Coverage | | ------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | cw1-subkeys | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw1_subkeys.wasm) | [![Docs](https://docs.rs/cw1-subkeys/badge.svg)](https://docs.rs/cw1-subkeys) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | @@ -21,7 +20,8 @@ | cw20-base | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_base.wasm) | [![Docs](https://docs.rs/cw20-base/badge.svg)](https://docs.rs/cw20-base) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | | cw20-ics20 | [Release v0.13.4](https://github.com/CosmWasm/cw-plus/releases/download/v0.13.4/cw20_ics20.wasm) | [![Docs](https://docs.rs/cw20-ics20/badge.svg)](https://docs.rs/cw20-ics20) | [![codecov](https://codecov.io/gh/CosmWasm/cw-plus/branch/main/graph/badge.svg?token=IYY72ZVS3X)](https://codecov.io/gh/CosmWasm/cw-plus) | -Note: `cw2` and `controllers` have been moved to the [`cw-minus` repo](https://github.com/CosmWasm/cw-minus) and can be followed there. +Note: `cw2` and `controllers` have been moved to the [`cw-minus` repo](https://github.com/CosmWasm/cw-minus) and can be +followed there. Note: `cw721` and `cw721-base` have moved to the new [`cw-nfts` repo](https://github.com/CosmWasm/cw-nfts) and can be followed there. @@ -102,7 +102,7 @@ To compile all the contracts, run the following in the repo root: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.13.0 + cosmwasm/optimizer:0.16.0 ``` This will compile all packages in the `contracts` directory and output the stripped and optimized wasm code under the diff --git a/scripts/optimizer.sh b/scripts/optimizer.sh index 966349ee4..2f5fa7483 100755 --- a/scripts/optimizer.sh +++ b/scripts/optimizer.sh @@ -1,7 +1,7 @@ : U="cosmwasm" -V="0.13.0" +V="0.16.0" M=$(uname -m) #M="x86_64" # Force Intel arch @@ -13,4 +13,4 @@ S=${S:+-$S} docker run --platform $A --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - $U/workspace-optimizer$S:$V + $U/optimizer$S:$V From b8812b7c4d1fa325d12ee95366ebb63094b46e0c Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 14 Jun 2024 12:51:53 +0200 Subject: [PATCH 630/631] Rename cargo configs --- contracts/cw1-subkeys/.cargo/{config => config.toml} | 0 contracts/cw1-whitelist/.cargo/{config => config.toml} | 0 contracts/cw20-base/.cargo/{config => config.toml} | 0 contracts/cw20-ics20/.cargo/{config => config.toml} | 0 contracts/cw3-fixed-multisig/.cargo/{config => config.toml} | 0 contracts/cw3-flex-multisig/.cargo/{config => config.toml} | 0 contracts/cw4-group/.cargo/{config => config.toml} | 0 contracts/cw4-stake/.cargo/{config => config.toml} | 0 packages/cw1/.cargo/{config => config.toml} | 0 packages/cw20/.cargo/{config => config.toml} | 0 packages/cw3/.cargo/{config => config.toml} | 0 packages/cw4/.cargo/{config => config.toml} | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename contracts/cw1-subkeys/.cargo/{config => config.toml} (100%) rename contracts/cw1-whitelist/.cargo/{config => config.toml} (100%) rename contracts/cw20-base/.cargo/{config => config.toml} (100%) rename contracts/cw20-ics20/.cargo/{config => config.toml} (100%) rename contracts/cw3-fixed-multisig/.cargo/{config => config.toml} (100%) rename contracts/cw3-flex-multisig/.cargo/{config => config.toml} (100%) rename contracts/cw4-group/.cargo/{config => config.toml} (100%) rename contracts/cw4-stake/.cargo/{config => config.toml} (100%) rename packages/cw1/.cargo/{config => config.toml} (100%) rename packages/cw20/.cargo/{config => config.toml} (100%) rename packages/cw3/.cargo/{config => config.toml} (100%) rename packages/cw4/.cargo/{config => config.toml} (100%) diff --git a/contracts/cw1-subkeys/.cargo/config b/contracts/cw1-subkeys/.cargo/config.toml similarity index 100% rename from contracts/cw1-subkeys/.cargo/config rename to contracts/cw1-subkeys/.cargo/config.toml diff --git a/contracts/cw1-whitelist/.cargo/config b/contracts/cw1-whitelist/.cargo/config.toml similarity index 100% rename from contracts/cw1-whitelist/.cargo/config rename to contracts/cw1-whitelist/.cargo/config.toml diff --git a/contracts/cw20-base/.cargo/config b/contracts/cw20-base/.cargo/config.toml similarity index 100% rename from contracts/cw20-base/.cargo/config rename to contracts/cw20-base/.cargo/config.toml diff --git a/contracts/cw20-ics20/.cargo/config b/contracts/cw20-ics20/.cargo/config.toml similarity index 100% rename from contracts/cw20-ics20/.cargo/config rename to contracts/cw20-ics20/.cargo/config.toml diff --git a/contracts/cw3-fixed-multisig/.cargo/config b/contracts/cw3-fixed-multisig/.cargo/config.toml similarity index 100% rename from contracts/cw3-fixed-multisig/.cargo/config rename to contracts/cw3-fixed-multisig/.cargo/config.toml diff --git a/contracts/cw3-flex-multisig/.cargo/config b/contracts/cw3-flex-multisig/.cargo/config.toml similarity index 100% rename from contracts/cw3-flex-multisig/.cargo/config rename to contracts/cw3-flex-multisig/.cargo/config.toml diff --git a/contracts/cw4-group/.cargo/config b/contracts/cw4-group/.cargo/config.toml similarity index 100% rename from contracts/cw4-group/.cargo/config rename to contracts/cw4-group/.cargo/config.toml diff --git a/contracts/cw4-stake/.cargo/config b/contracts/cw4-stake/.cargo/config.toml similarity index 100% rename from contracts/cw4-stake/.cargo/config rename to contracts/cw4-stake/.cargo/config.toml diff --git a/packages/cw1/.cargo/config b/packages/cw1/.cargo/config.toml similarity index 100% rename from packages/cw1/.cargo/config rename to packages/cw1/.cargo/config.toml diff --git a/packages/cw20/.cargo/config b/packages/cw20/.cargo/config.toml similarity index 100% rename from packages/cw20/.cargo/config rename to packages/cw20/.cargo/config.toml diff --git a/packages/cw3/.cargo/config b/packages/cw3/.cargo/config.toml similarity index 100% rename from packages/cw3/.cargo/config rename to packages/cw3/.cargo/config.toml diff --git a/packages/cw4/.cargo/config b/packages/cw4/.cargo/config.toml similarity index 100% rename from packages/cw4/.cargo/config rename to packages/cw4/.cargo/config.toml From dec6ebd6830da913e9308a6ad9211e60edbbd858 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 14 Jun 2024 13:04:28 +0200 Subject: [PATCH 631/631] Update cosmwasm-schema --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 605d7c97b..3912176c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a67c099aba9e334bbc1fc8037fe8e7ba91d06b215d9ffa7af91893c44aa420c6" +checksum = "101d0739564bd34cba9b84bf73665f0822487ae3b29b2dd59930608ed3aafd43" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2bb09168f6e86bf583361fdb0a0fed2625652e9edcfce731cb55ef4cb8de3d" +checksum = "cf4be75f60158478da2c5d319ed59295bca1687ad50c18215a0485aa91a995ea" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 179608252..9b1691eaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ resolver = "2" version = "2.0.0" [workspace.dependencies] -cosmwasm-schema = "2.0.0" +cosmwasm-schema = "2.0.2" cosmwasm-std = "2.0.2" cw2 = "2.0.0" cw-controllers = "2.0.0"