diff --git a/crates/lang/macro/src/lib.rs b/crates/lang/macro/src/lib.rs index f19bdbb5b35..55f2a201f90 100644 --- a/crates/lang/macro/src/lib.rs +++ b/crates/lang/macro/src/lib.rs @@ -136,8 +136,11 @@ pub fn selector_bytes(input: TokenStream) -> TokenStream { /// /// An example for this is the following type that could potentially be used /// within a contract's storage struct definition: -/// ``` -/// // A storage vector of storage vectors. +/// +/// +/// ```ignore +/// # // Tracking issue [#1119]: Right now we've hidden the `StorageVec` from public access so +/// # // this doesn't compile. /// # use ink_storage as storage; /// # type _unused = /// storage::Vec> diff --git a/crates/lang/tests/ui/contract/pass/example-erc20-works.rs b/crates/lang/tests/ui/contract/pass/example-erc20-works.rs index 81051b632c7..2f5b96661e2 100644 --- a/crates/lang/tests/ui/contract/pass/example-erc20-works.rs +++ b/crates/lang/tests/ui/contract/pass/example-erc20-works.rs @@ -3,11 +3,8 @@ use ink_lang as ink; #[ink::contract] mod erc20 { use ink_storage::{ - lazy::{ - Lazy, - Mapping, - }, traits::SpreadAllocate, + Mapping, }; /// A simple ERC-20 contract. @@ -15,7 +12,7 @@ mod erc20 { #[derive(SpreadAllocate)] pub struct Erc20 { /// Total token supply. - total_supply: Lazy, + total_supply: Balance, /// Mapping from owner to number of owned token. balances: Mapping, /// Mapping of the token amount which an account is allowed to withdraw @@ -70,7 +67,7 @@ mod erc20 { fn new_init(&mut self, initial_supply: Balance) { let caller = Self::env().caller(); self.balances.insert(&caller, &initial_supply); - Lazy::set(&mut self.total_supply, initial_supply); + self.total_supply = initial_supply; Self::env().emit_event(Transfer { from: None, to: Some(caller), @@ -81,7 +78,7 @@ mod erc20 { /// Returns the total token supply. #[ink(message)] pub fn total_supply(&self) -> Balance { - *self.total_supply + self.total_supply } /// Returns the account balance for the specified `owner`. diff --git a/crates/lang/tests/ui/contract/pass/example-erc721-works.rs b/crates/lang/tests/ui/contract/pass/example-erc721-works.rs index 13bc2a28290..f97a7e564aa 100644 --- a/crates/lang/tests/ui/contract/pass/example-erc721-works.rs +++ b/crates/lang/tests/ui/contract/pass/example-erc721-works.rs @@ -3,8 +3,8 @@ use ink_lang as ink; #[ink::contract] mod erc721 { use ink_storage::{ - lazy::Mapping, traits::SpreadAllocate, + Mapping, }; use scale::{ diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index e987e5f9e52..097fbf9700e 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -27,13 +27,6 @@ scale-info = { version = "1.0", default-features = false, features = ["derive"], cfg-if = "1.0" array-init = { version = "2.0", default-features = false } -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -# Workaround: we actually just need criterion as a dev-dependency, but -# there is an issue with a doubly included std lib when executing -# `cargo check --no-default-features --target wasm32-unknown-unknown`. -# We haven't found a better solution yet. -criterion = { version = "0.3", optional = true } - [dev-dependencies] quickcheck = "1.0" quickcheck_macros = "1.0" @@ -43,7 +36,6 @@ paste = "1.0" [features] default = ["std"] std = [ - "criterion", "ink_metadata", "ink_metadata/std", "ink_env/std", @@ -55,33 +47,3 @@ std = [ ] ink-fuzz-tests = ["std"] ink-experimental-engine = ["ink_env/ink-experimental-engine"] - -[[bench]] -name = "bench_lazy" -path = "benches/bench_lazy.rs" -harness = false - -[[bench]] -name = "bench_vec" -path = "benches/bench_vec.rs" -harness = false - -[[bench]] -name = "bench_stash" -path = "benches/bench_stash.rs" -harness = false - -[[bench]] -name = "bench_bitstash" -path = "benches/bench_bitstash.rs" -harness = false - -[[bench]] -name = "bench_hashmap" -path = "benches/bench_hashmap.rs" -harness = false - -[[bench]] -name = "bench_binary_heap" -path = "benches/bench_binary_heap.rs" -harness = false diff --git a/crates/storage/benches/bench_binary_heap.rs b/crates/storage/benches/bench_binary_heap.rs deleted file mode 100644 index 986dce287e9..00000000000 --- a/crates/storage/benches/bench_binary_heap.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - criterion_group, - criterion_main, - measurement::WallTime, - BatchSize, - BenchmarkGroup, - BenchmarkId, - Criterion, -}; -use ink_primitives::Key; -use ink_storage::{ - collections::BinaryHeap, - traits::{ - KeyPtr, - SpreadLayout, - }, -}; -use std::time::Duration; - -criterion_group!(push, bench_push_empty_cache, bench_push_populated_cache); -criterion_group!(pop, bench_pop_empty_cache, bench_pop_populated_cache); -criterion_main!(push, pop); - -/// Returns some test values for use in benchmarks. -fn test_values(n: u32) -> Vec { - std::iter::repeat(0u32) - .take(n as usize) - .enumerate() - .map(|(i, _)| i as u32 + 1) - .collect() -} - -mod binary_heap { - use super::*; - - /// Initialize the contract storage at the given key with the provided values. - /// - /// Use for testing lazy loading of a binary heap: an instance with an associated key which is - /// yet to load any elements from storage. This is the state a binary heap instance will be in - /// at the start of contract execution. - pub fn init_storage(root_key: Key, values: &[u32]) { - let heap = from_slice(values); - SpreadLayout::push_spread(&heap, &mut KeyPtr::from(root_key)); - - // prevents storage for the test heap being cleared when the heap is dropped after each - // benchmark iteration - ink_env::test::set_clear_storage_disabled(true); - } - - /// Creates a binary heap from the given slice. - pub fn from_slice(slice: &[u32]) -> BinaryHeap { - slice.iter().copied().collect::>() - } -} - -fn bench_push_empty_cache(c: &mut Criterion) { - bench_heap_sizes::<_, _, Push>( - c, - "BinaryHeap::push (empty cache)", - binary_heap::init_storage, - NewHeap::lazy, - ); -} - -fn bench_push_populated_cache(c: &mut Criterion) { - bench_heap_sizes::<_, _, Push>( - c, - "BinaryHeap::push (populated cache)", - |_: Key, _: &[u32]| {}, - NewHeap::populated, - ); -} - -fn bench_pop_empty_cache(c: &mut Criterion) { - bench_heap_sizes::<_, _, Pop>( - c, - "BinaryHeap::pop (empty cache)", - binary_heap::init_storage, - NewHeap::lazy, - ); -} - -fn bench_pop_populated_cache(c: &mut Criterion) { - bench_heap_sizes::<_, _, Pop>( - c, - "BinaryHeap::pop (populated cache)", - |_: Key, _: &[u32]| {}, - NewHeap::populated, - ); -} - -fn bench_heap_sizes(c: &mut Criterion, name: &str, init: I, new_test_heap: H) -where - I: Fn(Key, &[u32]), - H: Fn(Key, Vec) -> NewHeap, - B: Benchmark, -{ - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group(name); - group.warm_up_time(Duration::from_secs(6)); - group.measurement_time(Duration::from_secs(10)); - - for (key, size) in [(0u8, 8u32), (1, 16), (2, 32), (3, 64)].iter() { - let root_key = Key::from([*key; 32]); - let test_values = test_values(*size); - - // perform one time initialization for this heap size - init(root_key, &test_values); - - let test_heap = new_test_heap(root_key, test_values); - ::bench(&mut group, *size, test_heap) - } - - group.finish(); - Ok(()) - }) - .unwrap(); -} - -/// Strategies for constructing a binary heap instance for a benchmark routine -enum NewHeap { - /// Create a binary heap with an empty cache, values at the given key are loaded from storage - /// upon access. - /// - /// This simulates the state of a binary heap at the beginning of a smart - /// contract's execution. - Lazy(Key), - /// Create a binary heap with all the values loaded into the cache. - /// - /// This simulates the state of a binary heap once all elements have been accessed during smart - /// contract execution and loaded into the cache. - Populated(Vec), -} - -impl NewHeap { - pub fn lazy(key: Key, _values: Vec) -> Self { - Self::Lazy(key) - } - - pub fn populated(_key: Key, values: Vec) -> Self { - Self::Populated(values) - } - - pub fn create_heap(&self) -> BinaryHeap { - match self { - NewHeap::Lazy(root_key) => { - as SpreadLayout>::pull_spread(&mut KeyPtr::from( - *root_key, - )) - } - NewHeap::Populated(ref values) => binary_heap::from_slice(values), - } - } -} - -/// Define a benchmark for an operation to be run against different size binary heaps -trait Benchmark { - fn bench(group: &mut BenchmarkGroup, size: u32, new_heap: NewHeap); -} - -/// Benchmark [`BinaryHeap::push`] -enum Push {} - -impl Benchmark for Push { - fn bench(group: &mut BenchmarkGroup, size: u32, new_heap: NewHeap) { - let largest_value = size + 1; - group.bench_with_input( - BenchmarkId::new("largest value", size), - &largest_value, - |b, &value| { - b.iter_batched_ref( - || new_heap.create_heap(), - |heap| heap.push(value), - BatchSize::SmallInput, - ); - }, - ); - - let smallest_value = 0; - group.bench_with_input( - BenchmarkId::new("smallest value", size), - &smallest_value, - |b, &value| { - b.iter_batched_ref( - || new_heap.create_heap(), - |heap| heap.push(value), - BatchSize::SmallInput, - ); - }, - ); - } -} - -/// Benchmark [`BinaryHeap::pop`] -enum Pop {} - -impl Benchmark for Pop { - fn bench(group: &mut BenchmarkGroup, size: u32, new_heap: NewHeap) { - group.bench_function(BenchmarkId::from_parameter(size), |b| { - b.iter_batched_ref( - || new_heap.create_heap(), - |heap| heap.pop(), - BatchSize::SmallInput, - ); - }); - } -} diff --git a/crates/storage/benches/bench_bitstash.rs b/crates/storage/benches/bench_bitstash.rs deleted file mode 100644 index ec807390f4e..00000000000 --- a/crates/storage/benches/bench_bitstash.rs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - black_box, - criterion_group, - criterion_main, - BatchSize, - Criterion, -}; - -use ink_primitives::Key; -use ink_storage::{ - collections::BitStash, - traits::{ - KeyPtr, - SpreadLayout, - }, -}; - -const BENCH_ALLOCATIONS: u32 = 100_000; - -criterion_group!(populated_cache, bench_populated_cache,); -criterion_group!(empty_cache, bench_empty_cache,); -criterion_main!(populated_cache, empty_cache,); - -/// Creates a `BitStash` and pushes it to the contract storage. -fn push_stash() { - let stash = BitStash::default(); - let root_key = Key::from([0x00; 32]); - SpreadLayout::push_spread(&stash, &mut KeyPtr::from(root_key)); -} - -/// Creates a `BitStash` and pushes it to the contract storage. -fn push_stash_by_ref(stash: &BitStash) { - let root_key = Key::from([0x00; 32]); - SpreadLayout::push_spread(stash, &mut KeyPtr::from(root_key)); -} - -/// Pulls a lazily loading `BitStash` instance from the contract storage. -fn pull_stash() -> BitStash { - let root_key = Key::from([0x00; 32]); - ::pull_spread(&mut KeyPtr::from(root_key)) -} - -/// Executes only a single `put` operation on the stash. -pub fn one_put(stash: &mut BitStash) { - black_box(stash.put()); -} - -/// Returns a stash on which `100_000` `put` operations have been executed. -fn create_large_stash() -> BitStash { - let mut stash = BitStash::default(); - for _ in 0..100_000 { - stash.put(); - } - stash -} - -mod populated_cache { - use super::*; - - /// Executes `put` operations on a new `BitStash` exactly `BENCH_ALLOCATIONS` times. - pub fn fill_bitstash() { - let mut stash = BitStash::default(); - for _ in 0..BENCH_ALLOCATIONS { - black_box(stash.put()); - } - } -} - -fn bench_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group("Bench: populated cache"); - group.bench_function("fill_bitstash", |b| b.iter(populated_cache::fill_bitstash)); - group.bench_function("one_put", |b| { - b.iter_batched_ref(create_large_stash, one_put, BatchSize::SmallInput) - }); - group.finish(); -} - -mod empty_cache { - use super::*; - - /// Executes `put` operations on a new `BitStash` exactly `BENCH_ALLOCATIONS` times. - pub fn fill_bitstash() { - push_stash(); - let mut stash = pull_stash(); - for _ in 0..BENCH_ALLOCATIONS { - black_box(stash.put()); - } - } -} - -/// In this case we lazily instantiate a `BitStash` by first creating and storing -/// into the contract storage. We then load the stash from storage lazily in each -/// benchmark iteration. -fn bench_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group("Bench: empty cache"); - group.bench_function("fill_bitstash", |b| b.iter(empty_cache::fill_bitstash)); - group.bench_function("one_put", |b| { - b.iter_batched_ref( - || { - let stash = create_large_stash(); - push_stash_by_ref(&stash); - pull_stash() - }, - one_put, - BatchSize::SmallInput, - ) - }); - group.finish(); - Ok(()) - }) - .unwrap(); -} diff --git a/crates/storage/benches/bench_hashmap.rs b/crates/storage/benches/bench_hashmap.rs deleted file mode 100644 index d7792b01801..00000000000 --- a/crates/storage/benches/bench_hashmap.rs +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - black_box, - criterion_group, - criterion_main, - BatchSize, - Criterion, -}; - -use ink_primitives::Key; -use ink_storage::traits::{ - KeyPtr, - SpreadLayout, -}; - -#[cfg(test)] -macro_rules! gen_tests_for_backend { - ( $backend:ty ) => { - criterion_group!( - populated_cache, - bench_insert_populated_cache, - bench_remove_populated_cache, - ); - criterion_group!( - empty_cache, - bench_insert_empty_cache, - bench_remove_empty_cache, - ); - criterion_main!(populated_cache, empty_cache,); - - /// The number of `ENTIRES` denotes how many test values are put into - /// the hashmap used in these benchmarks. - const ENTRIES: i32 = 500; - - /// Returns some test values for use in benchmarks. - fn test_values() -> Vec<(i32, i32)> { - (0..ENTRIES) - .into_iter() - .map(|index| (index, index)) - .collect::>() - } - - /// Creates a hashmap from the given slice. - fn hashmap_from_slice(slice: &[(i32, i32)]) -> $backend { - slice.iter().copied().collect::<$backend>() - } - - /// Creates a hashmap from `test_values()`. - fn setup_hashmap() -> $backend { - let test_values = test_values(); - hashmap_from_slice(&test_values[..]) - } - - /// Returns always the same `KeyPtr`. - fn key_ptr() -> KeyPtr { - let root_key = Key::from([0x42; 32]); - KeyPtr::from(root_key) - } - - /// Creates a hashmap and pushes it to the contract storage. - fn push_storage_hashmap() { - let hmap = setup_hashmap(); - SpreadLayout::push_spread(&hmap, &mut key_ptr()); - } - - /// Pulls a lazily loading hashmap instance from the contract storage. - fn pull_storage_hashmap() -> $backend { - <$backend as SpreadLayout>::pull_spread(&mut key_ptr()) - } - - /// Iteratively checks if an entry is in the hashmap. If not, it - /// is inserted. In either case it is incremented afterwards. - fn insert_and_inc(hmap: &mut $backend) { - for key in 0..ENTRIES * 2 { - if !black_box(contains_key(hmap, &key)) { - black_box(insert(hmap, key, key)); - } - *black_box(hmap.get_mut(&key)).unwrap() += 1; - } - } - - /// Iteratively checks if an entry is in the hashmap. If not, it - /// is inserted. In either case it is incremented afterwards. - /// - /// Uses the Entry API. - fn insert_and_inc_entry_api(hmap: &mut $backend) { - for key in 0..ENTRIES * 2 { - let v = black_box(hmap.entry(key).or_insert(key)); - *v += 1; - } - } - - /// Iteratively checks if an entry is in the hashmap. If yes, it - /// is taken out. - fn remove(hmap: &mut $backend) { - for key in 0..ENTRIES * 2 { - if black_box(contains_key(hmap, &key)) { - let _ = black_box(take(hmap, &key)); - } - } - } - - /// Iteratively checks if an entry is in the hashmap. If yes, it - /// is taken out. - /// - /// Uses the Entry API. - fn remove_entry_api(hmap: &mut $backend) { - for key in 0..ENTRIES * 2 { - if let Entry::Occupied(o) = black_box(hmap.entry(key)) { - o.remove(); - } - } - } - - fn bench_insert_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group( - format!("{} Compare: `insert_and_inc` and `insert_and_inc_entry_api` (populated cache)", stringify!($backend)) - ); - group.bench_function("insert_and_inc", |b| { - b.iter_batched_ref( - setup_hashmap, - |hmap| insert_and_inc(hmap), - BatchSize::SmallInput, - ) - }); - group.bench_function("insert_and_inc_entry_api", |b| { - b.iter_batched_ref( - setup_hashmap, - |hmap| insert_and_inc_entry_api(hmap), - BatchSize::SmallInput, - ) - }); - group.finish(); - } - - fn bench_remove_populated_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group( - format!("{} Compare: `remove` and `remove_entry_api` (populated cache)", stringify!($backend)) - ); - group.bench_function("remove", |b| { - b.iter_batched_ref( - setup_hashmap, - |hmap| remove(hmap), - BatchSize::SmallInput, - ) - }); - group.bench_function("remove_entry_api", |b| { - b.iter_batched_ref( - setup_hashmap, - |hmap| remove_entry_api(hmap), - BatchSize::SmallInput, - ) - }); - group.finish(); - Ok(()) - }) - .unwrap(); - } - - fn bench_insert_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group( - format!("{} Compare: `insert_and_inc` and `insert_and_inc_entry_api` (empty cache)", stringify!($backend)) - ); - group.bench_function("insert_and_inc", |b| { - b.iter_batched_ref( - || { - push_storage_hashmap(); - pull_storage_hashmap() - }, - |hmap| insert_and_inc(hmap), - BatchSize::SmallInput, - ) - }); - group.bench_function("insert_and_inc_entry_api", |b| { - b.iter_batched_ref( - || { - push_storage_hashmap(); - pull_storage_hashmap() - }, - |hmap| insert_and_inc_entry_api(hmap), - BatchSize::SmallInput, - ) - }); - group.finish(); - Ok(()) - }) - .unwrap(); - } - - fn bench_remove_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = - c.benchmark_group(format!("{} Compare: `remove` and `remove_entry_api` (empty cache)", stringify!($backend))); - group.bench_function("remove", |b| { - b.iter_batched_ref( - || { - push_storage_hashmap(); - pull_storage_hashmap() - }, - |hmap| remove(hmap), - BatchSize::SmallInput, - ) - }); - group.bench_function("remove_entry_api", |b| { - b.iter_batched_ref( - || { - push_storage_hashmap(); - pull_storage_hashmap() - }, - |hmap| remove_entry_api(hmap), - BatchSize::SmallInput, - ) - }); - group.finish(); - Ok(()) - }) - .unwrap(); - } - }; -} - -mod lazyhmap_backend { - use super::*; - use ink_env::hash::Blake2x256; - use ink_storage::lazy::lazy_hmap::{ - Entry, - LazyHashMap, - }; - - gen_tests_for_backend!(LazyHashMap); - - pub fn insert( - hmap: &mut LazyHashMap, - key: i32, - value: i32, - ) -> Option { - hmap.put_get(&key, Some(value)) - } - - pub fn take(hmap: &mut LazyHashMap, key: &i32) -> Option { - hmap.put_get(key, None) - } - - pub fn contains_key(hmap: &LazyHashMap, key: &i32) -> bool { - hmap.get(key).is_some() - } - - pub fn run() { - self::main() - } -} - -mod hashmap_backend { - use super::*; - use ink_storage::collections::{ - hashmap::Entry, - HashMap as StorageHashMap, - }; - - gen_tests_for_backend!(StorageHashMap); - - pub fn insert( - hmap: &mut StorageHashMap, - key: i32, - value: i32, - ) -> Option { - hmap.insert(key, value) - } - - pub fn take(hmap: &mut StorageHashMap, key: &i32) -> Option { - hmap.take(key) - } - - pub fn contains_key(hmap: &StorageHashMap, key: &i32) -> bool { - hmap.contains_key(key) - } - - pub fn run() { - self::main() - } -} - -fn main() { - hashmap_backend::run(); - lazyhmap_backend::run(); -} diff --git a/crates/storage/benches/bench_lazy.rs b/crates/storage/benches/bench_lazy.rs deleted file mode 100644 index 55010691245..00000000000 --- a/crates/storage/benches/bench_lazy.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - black_box, - criterion_group, - criterion_main, - BenchmarkId, - Criterion, -}; -use ink_primitives::Key; -use ink_storage::{ - lazy::Lazy, - traits::{ - KeyPtr, - SpreadLayout, - }, -}; - -criterion_group!(populated_cache, bench_set_populated_cache); -criterion_group!(empty_cache, bench_set_empty_cache,); -criterion_main!(populated_cache, empty_cache); - -mod populated_cache { - use super::*; - use core::ops::DerefMut; - - pub fn set() { - let mut lazy = >::new(1); - let lazy_mut = black_box(&mut lazy); - let _ = black_box(|| Lazy::set(lazy_mut, 17)); - } - - pub fn deref_mut() { - let mut lazy = >::new(1); - let i32_mut = black_box(lazy.deref_mut()); - let _ = black_box(|| *i32_mut = 17); - } -} - -fn bench_set_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group("Compare: `set` and `deref_mut` (populated cache)"); - group.bench_function(BenchmarkId::new("set", 0), |b| b.iter(populated_cache::set)); - group.bench_function(BenchmarkId::new("deref_mut", 0), |b| { - b.iter(populated_cache::deref_mut) - }); - group.finish(); -} - -/// Pushes a value to contract storage and creates a `Lazy` pointing to it. -fn push_storage_lazy(value: i32) -> Lazy { - let root_key = Key::from([0x00; 32]); - SpreadLayout::push_spread(&Lazy::new(value), &mut KeyPtr::from(root_key)); - SpreadLayout::pull_spread(&mut KeyPtr::from(root_key)) -} - -mod empty_cache { - use super::*; - - pub fn set() { - let mut lazy = push_storage_lazy(1); - let _ = black_box(|| Lazy::set(&mut lazy, 13)); - } - - pub fn deref_mut() { - let mut lazy = push_storage_lazy(1); - let _ = black_box(|| *lazy = 13); - } -} - -fn bench_set_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group("Compare: `set` and `deref_mut` (empty cache)"); - group.bench_function(BenchmarkId::new("set", 0), |b| b.iter(empty_cache::set)); - group.bench_function(BenchmarkId::new("deref_mut", 0), |b| { - b.iter(empty_cache::deref_mut) - }); - group.finish(); - Ok(()) - }) - .unwrap(); -} diff --git a/crates/storage/benches/bench_stash.rs b/crates/storage/benches/bench_stash.rs deleted file mode 100644 index 8938a15e050..00000000000 --- a/crates/storage/benches/bench_stash.rs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - black_box, - criterion_group, - criterion_main, - Criterion, -}; -use ink_primitives::Key; -use ink_storage::{ - collections::Stash as StorageStash, - traits::{ - KeyPtr, - SpreadLayout, - }, -}; - -criterion_group!(populated_cache, bench_remove_occupied_populated_cache,); -criterion_group!(empty_cache, bench_remove_occupied_empty_cache,); -criterion_main!(populated_cache, empty_cache,); - -/// Returns some test values for use in benchmarks. -#[rustfmt::skip] -fn test_values() -> &'static [u8] { - &[ - b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', - b'A', b'B', b'C', b'D', b'E', b'F' - ] -} - -/// Creates a storage stash from the given slice. -fn storage_stash_from_slice(slice: &[u8]) -> StorageStash { - slice.iter().copied().collect::>() -} - -/// Creates a storage stash and pushes it to the contract storage. -fn push_storage_stash() { - let stash = storage_stash_from_slice(test_values()); - let root_key = Key::from([0x00; 32]); - SpreadLayout::push_spread(&stash, &mut KeyPtr::from(root_key)); -} - -/// Pulls a lazily loading storage stash instance from the contract storage. -fn pull_storage_stash() -> StorageStash { - let root_key = Key::from([0x00; 32]); - as SpreadLayout>::pull_spread(&mut KeyPtr::from(root_key)) -} - -mod populated_cache { - use super::*; - - pub fn remove_occupied_all(test_values: &[u8]) { - let mut stash = storage_stash_from_slice(test_values); - for (index, _value) in test_values.iter().enumerate() { - black_box(unsafe { stash.remove_occupied(index as u32) }); - } - } - - pub fn take_all(test_values: &[u8]) { - let mut stash = storage_stash_from_slice(test_values); - for (index, _value) in test_values.iter().enumerate() { - black_box(stash.take(index as u32)); - } - } -} - -fn bench_remove_occupied_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group( - "Compare: `remove_occupied_all` and `take_all` (populated cache)", - ); - let test_values = [b'A', b'B', b'C', b'D', b'E', b'F']; - group.bench_with_input("remove_occupied_all", &test_values, |b, i| { - b.iter(|| populated_cache::remove_occupied_all(i)) - }); - group.bench_with_input("take_all", &test_values, |b, i| { - b.iter(|| populated_cache::take_all(i)) - }); - group.finish(); -} - -mod empty_cache { - use super::*; - - /// In this case we lazily load the stash from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - pub fn remove_occupied_all() { - push_storage_stash(); - let mut stash = pull_storage_stash(); - for index in 0..stash.len() { - black_box(unsafe { stash.remove_occupied(index) }); - } - } - - /// In this case we lazily load the stash from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - /// `take` will then result in loading from storage. - pub fn take_all() { - push_storage_stash(); - let mut stash = pull_storage_stash(); - for index in 0..stash.len() { - black_box(stash.take(index)); - } - } -} - -/// In this case we lazily instantiate a `StorageStash` by first `create_and_store`-ing -/// into the contract storage. We then load the stash from storage lazily in each -/// benchmark iteration. -fn bench_remove_occupied_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group( - "Compare: `remove_occupied_all` and `take_all` (empty cache)", - ); - group.bench_function("remove_occupied_all", |b| { - b.iter(empty_cache::remove_occupied_all) - }); - group.bench_function("take_all", |b| b.iter(empty_cache::take_all)); - group.finish(); - Ok(()) - }) - .unwrap(); -} diff --git a/crates/storage/benches/bench_vec.rs b/crates/storage/benches/bench_vec.rs deleted file mode 100644 index 2fc62791d8f..00000000000 --- a/crates/storage/benches/bench_vec.rs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// 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. - -use criterion::{ - black_box, - criterion_group, - criterion_main, - BenchmarkId, - Criterion, -}; -use ink_primitives::Key; -use ink_storage::{ - collections::Vec as StorageVec, - traits::{ - KeyPtr, - SpreadLayout, - }, -}; - -criterion_group!( - populated_cache, - bench_clear_populated_cache, - bench_put_populated_cache, -); -criterion_group!(empty_cache, bench_clear_empty_cache, bench_put_empty_cache,); -criterion_main!(populated_cache, empty_cache,); - -/// Returns some test values for use in benchmarks. -#[rustfmt::skip] -fn test_values() -> &'static [u8] { - &[ - b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', - b'A', b'B', b'C', b'D', b'E', b'F' - ] -} - -/// Creates a storage vector from the given slice. -fn storage_vec_from_slice(slice: &[u8]) -> StorageVec { - slice.iter().copied().collect::>() -} - -/// Creates a storage vector and pushes it to the contract storage. -fn push_storage_vec() { - let vec = storage_vec_from_slice(test_values()); - let root_key = Key::from([0x00; 32]); - SpreadLayout::push_spread(&vec, &mut KeyPtr::from(root_key)); -} - -/// Pulls a lazily loading storage vector instance from the contract storage. -fn pull_storage_vec() -> StorageVec { - let root_key = Key::from([0x00; 32]); - as SpreadLayout>::pull_spread(&mut KeyPtr::from(root_key)) -} - -mod populated_cache { - use super::*; - - pub fn clear(test_values: &[u8]) { - let mut vec = storage_vec_from_slice(test_values); - let _ = black_box(|| vec.clear()); - } - - pub fn pop_all(test_values: &[u8]) { - let mut vec = storage_vec_from_slice(test_values); - while let Some(ignored) = black_box(vec.pop()) { - black_box(ignored); - } - } - - pub fn set(test_values: &[u8]) { - let mut vec = storage_vec_from_slice(test_values); - for (index, _value) in test_values.iter().enumerate() { - let _ = black_box(vec.set(index as u32, b'X')); - } - } - - pub fn get_mut(test_values: &[u8]) { - let mut vec = storage_vec_from_slice(test_values); - for (index, _value) in test_values.iter().enumerate() { - *black_box(vec.get_mut(index as u32).unwrap()) = b'X'; - } - } -} - -fn bench_put_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group("Compare: `set` and `get_mut` (populated cache)"); - group.bench_with_input(BenchmarkId::new("set", 0), test_values(), |b, i| { - b.iter(|| populated_cache::set(i)) - }); - group.bench_with_input(BenchmarkId::new("get_mut", 0), test_values(), |b, i| { - b.iter(|| populated_cache::get_mut(i)) - }); - group.finish(); -} - -fn bench_clear_populated_cache(c: &mut Criterion) { - let mut group = c.benchmark_group("Compare: `clear` and `pop_all` (populated cache)"); - let test_values = [b'A', b'B', b'C', b'D', b'E', b'F']; - group.bench_with_input("clear", &test_values, |b, i| { - b.iter(|| populated_cache::clear(i)) - }); - group.bench_with_input("pop_all", &test_values, |b, i| { - b.iter(|| populated_cache::pop_all(i)) - }); - group.finish(); -} - -mod empty_cache { - use super::*; - - /// In this case we lazily load the vec from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - pub fn clear() { - push_storage_vec(); - let mut vec = pull_storage_vec(); - let _ = black_box(|| vec.clear()); - } - - /// In this case we lazily load the vec from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - /// `pop` will then result in loading from storage. - pub fn pop_all() { - push_storage_vec(); - let mut vec = pull_storage_vec(); - while let Some(ignored) = black_box(vec.pop()) { - black_box(ignored); - } - } - - /// In this case we lazily load the vec from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - /// The `deref` will then load from storage. - pub fn get_mut() { - push_storage_vec(); - let mut vec = pull_storage_vec(); - for index in 0..vec.len() { - *black_box(vec.get_mut(index).unwrap()) = b'X'; - } - } - - /// In this case we lazily load the vec from storage using `pull_spread`. - /// This will just load lazily and won't pull anything from the storage. - /// The `vec.set()` will not load anything from storage. - pub fn set() { - push_storage_vec(); - let mut vec = pull_storage_vec(); - for index in 0..vec.len() { - let _ = black_box(vec.set(index, b'X')); - } - } -} - -/// In this case we lazily instantiate a `StorageVec` by first `create_and_store`-ing -/// into the contract storage. We then load the vec from storage lazily in each -/// benchmark iteration. -fn bench_clear_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group("Compare: `clear` and `pop_all` (empty cache)"); - group.bench_function("clear", |b| b.iter(empty_cache::clear)); - group.bench_function("pop_all", |b| b.iter(empty_cache::pop_all)); - group.finish(); - Ok(()) - }) - .unwrap(); -} - -/// In this case we lazily instantiate a `StorageVec` by first `create_and_store`-ing -/// into the contract storage. We then load the vec from storage lazily in each -/// benchmark iteration. -fn bench_put_empty_cache(c: &mut Criterion) { - let _ = ink_env::test::run_test::(|_| { - let mut group = c.benchmark_group("Compare: `set` and `get_mut` (empty cache)"); - group.bench_function("set", |b| b.iter(empty_cache::set)); - group.bench_function("get_mut", |b| b.iter(empty_cache::get_mut)); - group.finish(); - Ok(()) - }) - .unwrap(); -} diff --git a/crates/storage/src/alloc/allocation.rs b/crates/storage/src/alloc/allocation.rs index 57848680927..542d0aac51b 100644 --- a/crates/storage/src/alloc/allocation.rs +++ b/crates/storage/src/alloc/allocation.rs @@ -26,11 +26,6 @@ use ink_primitives::Key; /// The initiator of the allocation has to make sure to deallocate /// this dynamic allocation again using the same dynamic allocator /// if it is no longer in use. -/// -/// # Note -/// -/// Normally instances of this type are not used directly and instead -/// a [`storage::Box`](`crate::Box`) is used instead. #[derive( Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, scale::Encode, scale::Decode, )] diff --git a/crates/storage/src/alloc/mod.rs b/crates/storage/src/alloc/mod.rs index b161151d8e3..8223cc66d9e 100644 --- a/crates/storage/src/alloc/mod.rs +++ b/crates/storage/src/alloc/mod.rs @@ -70,6 +70,10 @@ mod allocation; mod allocator; + +// Tracking issue [#1119]: We allow `dead_code` here since we're purposefully hiding the `box` +// module and will remove at a later time. +#[allow(dead_code)] mod boxed; mod init; @@ -79,7 +83,6 @@ mod tests; use self::allocator::DynamicAllocator; pub use self::{ allocation::DynamicAllocation, - boxed::Box, init::ContractPhase, }; diff --git a/crates/storage/src/collections/binary_heap/mod.rs b/crates/storage/src/collections/binary_heap/mod.rs index 45cbd68601e..e8d6ff04c9d 100644 --- a/crates/storage/src/collections/binary_heap/mod.rs +++ b/crates/storage/src/collections/binary_heap/mod.rs @@ -106,7 +106,9 @@ where /// /// # Example /// - /// ``` + /// ```ignore + /// # // Tracking issue [#1119]: We currently ignore this test since we stopped exposing + /// # // `collections` publicly. /// use ink_storage::collections::BinaryHeap; /// let mut heap = BinaryHeap::new(); /// assert!(heap.peek_mut().is_none()); diff --git a/crates/storage/src/collections/vec/mod.rs b/crates/storage/src/collections/vec/mod.rs index 900347b4e88..4626a9f3fc0 100644 --- a/crates/storage/src/collections/vec/mod.rs +++ b/crates/storage/src/collections/vec/mod.rs @@ -220,7 +220,9 @@ where /// uniquely determined position; the second and third are not /// found; the fourth could match any position in `[1, 4]`. /// - /// ``` + /// ```ignore + /// # // Tracking issue [#1119]: We currently ignore this test since we stopped exposing + /// # // `StorageVec` publicly. /// use ink_storage::Vec as StorageVec; /// /// let s: StorageVec = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] @@ -265,7 +267,9 @@ where /// uniquely determined position; the second and third are not /// found; the fourth could match any position in `[1, 4]`. /// - /// ``` + /// ```ignore + /// # // Tracking issue [#1119]: We currently ignore this test since we stopped exposing + /// # // `StorageVec` publicly. /// use ink_storage::Vec as StorageVec; /// /// let s: StorageVec = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] @@ -338,7 +342,9 @@ where /// determined position; the second and third are not found; the /// fourth could match any position in `[1, 4]`. /// - /// ``` + /// ```ignore + /// # // Tracking issue [#1119]: We currently ignore this test since we stopped exposing + /// # // `StorageVec` publicly. /// use ink_storage::Vec as StorageVec; /// /// let s: StorageVec<(i32, i32)> = [ diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index f26792f3e79..17aeb9a4ed0 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -48,11 +48,17 @@ extern crate quickcheck_macros; pub mod alloc; -pub mod collections; -pub mod lazy; +pub mod traits; + +// Tracking issue [#1119]: We allow `dead_code` here since we're purposefully hiding the +// collections and will remove them at a later time. +#[allow(dead_code)] +pub(crate) mod collections; +#[allow(dead_code)] +pub(crate) mod lazy; + mod memory; mod pack; -pub mod traits; #[cfg(test)] mod hashmap_entry_api_tests; @@ -62,9 +68,13 @@ mod test_utils; #[doc(inline)] pub use self::{ - alloc::Box, + lazy::Mapping, + memory::Memory, +}; + +#[doc(inline)] +pub(crate) use self::{ collections::Vec, lazy::Lazy, - memory::Memory, pack::Pack, }; diff --git a/crates/storage/src/traits/packed.rs b/crates/storage/src/traits/packed.rs index 306303315df..97c654765b6 100644 --- a/crates/storage/src/traits/packed.rs +++ b/crates/storage/src/traits/packed.rs @@ -25,8 +25,6 @@ pub trait PackedAllocate: SpreadAllocate + PackedLayout { /// # Note /// /// Most types will have to implement a trivial forwarding to their fields. - /// However, some types such as [`storage::Box`](`crate::Box`) - /// are required to perform some special handling upon receiving this signal. fn allocate_packed(&mut self, at: &Key); } @@ -37,8 +35,6 @@ pub trait PackedLayout: SpreadLayout + scale::Encode + scale::Decode { /// # Note /// /// Most types will have to implement a trivial forwarding to their fields. - /// However, some types such as [`storage::Box`](`crate::Box`) - /// are required to perform some special handling upon receiving this signal. fn pull_packed(&mut self, at: &Key); /// Indicates to `self` that it is about to be pushed to contract storage. @@ -46,8 +42,6 @@ pub trait PackedLayout: SpreadLayout + scale::Encode + scale::Decode { /// # Note /// /// Most types will have to implement a trivial forwarding to their fields. - /// However, some types such as [`storage::Box`](`crate::Box`) - /// are required to perform some special handling upon receiving this signal. fn push_packed(&self, at: &Key); /// Indicates to `self` that it is about to be cleared from contract storage. @@ -55,7 +49,5 @@ pub trait PackedLayout: SpreadLayout + scale::Encode + scale::Decode { /// # Note /// /// Most types will have to implement a trivial forwarding to their fields. - /// However, some types such as [`storage::Box`](`crate::Box`) - /// are required to perform some special handling upon receiving this signal. fn clear_packed(&self, at: &Key); } diff --git a/examples/delegator/lib.rs b/examples/delegator/lib.rs index 151b678bddd..df399425f31 100644 --- a/examples/delegator/lib.rs +++ b/examples/delegator/lib.rs @@ -6,12 +6,9 @@ use ink_lang as ink; mod delegator { use accumulator::AccumulatorRef; use adder::AdderRef; - use ink_storage::{ - traits::{ - PackedLayout, - SpreadLayout, - }, - Lazy, + use ink_storage::traits::{ + PackedLayout, + SpreadLayout, }; use subber::SubberRef; @@ -59,11 +56,11 @@ mod delegator { /// Says which of `adder` or `subber` is currently in use. which: Which, /// The `accumulator` smart contract. - accumulator: Lazy, + accumulator: AccumulatorRef, /// The `adder` smart contract. - adder: Lazy, + adder: AdderRef, /// The `subber` smart contract. - subber: Lazy, + subber: SubberRef, } impl Delegator { @@ -107,9 +104,9 @@ mod delegator { }); Self { which: Which::Adder, - accumulator: Lazy::new(accumulator), - adder: Lazy::new(adder), - subber: Lazy::new(subber), + accumulator, + adder, + subber, } } diff --git a/examples/dns/lib.rs b/examples/dns/lib.rs index 2037586a7ba..80342142ead 100644 --- a/examples/dns/lib.rs +++ b/examples/dns/lib.rs @@ -5,11 +5,8 @@ use ink_lang as ink; #[ink::contract] mod dns { use ink_storage::{ - lazy::{ - Lazy, - Mapping, - }, traits::SpreadAllocate, + Mapping, }; /// Emitted whenever a new name is being registered. @@ -68,7 +65,7 @@ mod dns { /// A hashmap to store all name to owners mapping. name_to_owner: Mapping, /// The default address. - default_address: Lazy, + default_address: AccountId, } /// Errors that can occur upon calling this contract. @@ -166,14 +163,14 @@ mod dns { fn get_owner_or_default(&self, name: Hash) -> AccountId { self.name_to_owner .get(&name) - .unwrap_or(*self.default_address) + .unwrap_or(self.default_address) } /// Returns the address given the hash or the default address. fn get_address_or_default(&self, name: Hash) -> AccountId { self.name_to_address .get(&name) - .unwrap_or(*self.default_address) + .unwrap_or(self.default_address) } } diff --git a/examples/erc1155/lib.rs b/examples/erc1155/lib.rs index 0f3f925d952..7360d0ae654 100644 --- a/examples/erc1155/lib.rs +++ b/examples/erc1155/lib.rs @@ -188,12 +188,12 @@ mod erc1155 { use super::*; use ink_storage::{ - lazy::Mapping, traits::{ PackedLayout, SpreadAllocate, SpreadLayout, }, + Mapping, }; /// Indicate that a token transfer has occured. diff --git a/examples/erc20/lib.rs b/examples/erc20/lib.rs index 288b36b3512..a767914fdf9 100644 --- a/examples/erc20/lib.rs +++ b/examples/erc20/lib.rs @@ -5,11 +5,8 @@ use ink_lang as ink; #[ink::contract] mod erc20 { use ink_storage::{ - lazy::{ - Lazy, - Mapping, - }, traits::SpreadAllocate, + Mapping, }; /// A simple ERC-20 contract. @@ -17,7 +14,7 @@ mod erc20 { #[derive(SpreadAllocate)] pub struct Erc20 { /// Total token supply. - total_supply: Lazy, + total_supply: Balance, /// Mapping from owner to number of owned token. balances: Mapping, /// Mapping of the token amount which an account is allowed to withdraw @@ -72,7 +69,7 @@ mod erc20 { fn new_init(&mut self, initial_supply: Balance) { let caller = Self::env().caller(); self.balances.insert(&caller, &initial_supply); - Lazy::set(&mut self.total_supply, initial_supply); + self.total_supply = initial_supply; Self::env().emit_event(Transfer { from: None, to: Some(caller), @@ -83,7 +80,7 @@ mod erc20 { /// Returns the total token supply. #[ink(message)] pub fn total_supply(&self) -> Balance { - *self.total_supply + self.total_supply } /// Returns the account balance for the specified `owner`. diff --git a/examples/erc721/lib.rs b/examples/erc721/lib.rs index 10800443ff6..919937d80f4 100644 --- a/examples/erc721/lib.rs +++ b/examples/erc721/lib.rs @@ -55,8 +55,8 @@ use ink_lang as ink; #[ink::contract] mod erc721 { use ink_storage::{ - lazy::Mapping, traits::SpreadAllocate, + Mapping, }; use scale::{ diff --git a/examples/multisig/lib.rs b/examples/multisig/lib.rs index c7233f16460..cc2d4174733 100755 --- a/examples/multisig/lib.rs +++ b/examples/multisig/lib.rs @@ -71,13 +71,12 @@ mod multisig { }; use ink_prelude::vec::Vec; use ink_storage::{ - lazy::Mapping, traits::{ PackedLayout, SpreadAllocate, SpreadLayout, }, - Lazy, + Mapping, }; use scale::Output; @@ -148,7 +147,9 @@ mod multisig { /// This is a book keeping struct that stores a list of all transaction ids and /// also the next id to use. We need it for cleaning up the storage. - #[derive(scale::Encode, scale::Decode, SpreadLayout, PackedLayout, Default)] + #[derive( + scale::Encode, scale::Decode, SpreadLayout, PackedLayout, SpreadAllocate, Default, + )] #[cfg_attr( feature = "std", derive( @@ -259,10 +260,10 @@ mod multisig { transactions: Mapping, /// We need to hold a list of all transactions so that we can clean up storage /// when an owner is removed. - transaction_list: Lazy, + transaction_list: Transactions, /// The list is a vector because iterating over it is necessary when cleaning /// up the confirmation set. - owners: Lazy>, + owners: Vec, /// Redundant information to speed up the check whether a caller is an owner. is_owner: Mapping, /// Minimum number of owners that have to confirm a transaction to be executed. @@ -289,7 +290,7 @@ mod multisig { contract.is_owner.insert(owner, &()); } - contract.owners = owners.into(); + contract.owners = owners; contract.transaction_list = Default::default(); contract.requirement = requirement; }) diff --git a/examples/trait-erc20/lib.rs b/examples/trait-erc20/lib.rs index 087816f7a2f..66665fcf9d4 100644 --- a/examples/trait-erc20/lib.rs +++ b/examples/trait-erc20/lib.rs @@ -6,11 +6,8 @@ use ink_lang as ink; mod erc20 { use ink_lang as ink; use ink_storage::{ - lazy::{ - Lazy, - Mapping, - }, traits::SpreadAllocate, + Mapping, }; /// The ERC-20 error types. @@ -65,7 +62,7 @@ mod erc20 { #[derive(SpreadAllocate)] pub struct Erc20 { /// Total token supply. - total_supply: Lazy, + total_supply: Balance, /// Mapping from owner to number of owned token. balances: Mapping, /// Mapping of the token amount which an account is allowed to withdraw @@ -109,7 +106,7 @@ mod erc20 { fn new_init(&mut self, initial_supply: Balance) { let caller = Self::env().caller(); self.balances.insert(&caller, &initial_supply); - Lazy::set(&mut self.total_supply, initial_supply); + self.total_supply = initial_supply; Self::env().emit_event(Transfer { from: None, to: Some(caller), @@ -122,7 +119,7 @@ mod erc20 { /// Returns the total token supply. #[ink(message)] fn total_supply(&self) -> Balance { - *self.total_supply + self.total_supply } /// Returns the account balance for the specified `owner`.