Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port multisig example to low level data structures #1078

Merged
merged 9 commits into from
Dec 14, 2021
Merged

Conversation

athei
Copy link
Contributor

@athei athei commented Dec 10, 2021

This removes all usages of data structures in collections. The new code shows some pain points of ink! and the pallet-contracts when removing those collections. I think this is exactly the reason why we should port this example with sub optimal code: We can come back, iterate and observe the improvements.

These are some pain point of the contract which could be fixed but would change the interface so I did leave them as is:

  1. Owners are stored in a packed Vec. The complexity of adding and removing owners scales linearly with the amount of owners. We might need to cap them.
  2. The transactions id are generated from a monotonic counter which will run out if ids eventually. I don't think this will be an issue in practice but we might want to either provide a "defrag" function or let the user pass in the id. I would prefer the latter but it will change the interface.

It also shows some shortcomings of the pallet-contracts map interface. I think we want the following functionality to paller-contracts:

  1. When setting a key in a mapping we want to return whether this key already existed
  2. Check for existence without reading the value
  3. Allow to get and remove and the same time (take)

@athei athei marked this pull request as ready for review December 10, 2021 16:27
There's no way to get the length of a `Mapping` so it doesn't make sense
to check this in tests anymore
@HCastano
Copy link
Contributor

Since we don't have the ink-waterfall running I checked the size differences locally:

Reference Original Optimized
master 108.5K 48.2K
PR 67.7K, 31.2K

A gain of 17K, not bad 😎

pub struct Mapping<K, V> {
offset_key: Key,
_marker: PhantomData<fn() -> (K, V)>,
}

/// We implement this manually because the derived implementation adds trait bounds.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What additional trait bounds are added here?

I checked the cargo-expand-ed contracts using both versions and there was no difference between them.

Copy link
Contributor Author

@athei athei Dec 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Default derive requires Default for each type parameter. But for this Mapping we don't need these bounds. In substrate we have a DefaultNoBounds derive for this.

if self.confirmations.get(&key).is_some() {
self.confirmations.remove(&key);
let mut count = self.confirmation_count.get(&trans_id).unwrap_or(0);
count += 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, seems it is a bug, it should be -1=)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right. Thanks for catching this.

@xgreenx
Copy link
Collaborator

xgreenx commented Dec 11, 2021

I tried to implement multisig by another way, I think it is more clear=) #1079

What do you think?

@athei
Copy link
Contributor Author

athei commented Dec 13, 2021

I tried to implement multisig by another way, I think it is more clear=) #1079

What do you think?

I think the idea is interesting. But please let us merge this "port only" PR first once the waterfall is up and running. Your PR adds some further changes to the contract and also breaks the interface. This isn't bad but I would like to do this separately (it is based on this PR anyways).

@athei
Copy link
Contributor Author

athei commented Dec 13, 2021

Removing lazy from requirement reduced size to 28.4K.

@codecov-commenter
Copy link

Codecov Report

Merging #1078 (245bbf0) into master (9ed2f48) will decrease coverage by 16.08%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##           master    #1078       +/-   ##
===========================================
- Coverage   78.77%   62.69%   -16.09%     
===========================================
  Files         248      248               
  Lines        9362     9360        -2     
===========================================
- Hits         7375     5868     -1507     
- Misses       1987     3492     +1505     
Impacted Files Coverage Δ
crates/storage/src/lazy/mapping.rs 100.00% <ø> (ø)
crates/lang/codegen/src/traits.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/ir/src/ir/contract.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/env.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/mod.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/enforced_error.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/blake2b.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/storage.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/arg_list.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/lang/codegen/src/generator/contract.rs 0.00% <0.00%> (-100.00%) ⬇️
... and 51 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9ed2f48...245bbf0. Read the comment docs.

@HCastano
Copy link
Contributor

These are the final numbers I get:

Original wasm size: 66.4K, Optimized: 29.9K

Gonna merge this since it's quite an improvement over what we have.

@HCastano HCastano merged commit bee7f73 into master Dec 14, 2021
@HCastano HCastano deleted the at-port-multisig branch December 14, 2021 18:54
xgreenx pushed a commit to Supercolony-net/ink that referenced this pull request Feb 8, 2022
* Fix `Default` impl of `Mapping`

* Replace HashMap by Mapping

* Use initialize_contract

* Initialize everything within `initialize_contract`

* Make owners lazy

* Remove commented out code

There's no way to get the length of a `Mapping` so it doesn't make sense
to check this in tests anymore

* Fix - + bug

* No need to make a primitive lazy

* Clippy

Co-authored-by: Hernando Castano <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants