Skip to content

Design: Compute static storage allocations at contract compile-time #246

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

Closed
Robbepop opened this issue Nov 17, 2019 · 1 comment
Closed
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request

Comments

@Robbepop
Copy link
Collaborator

Robbepop commented Nov 17, 2019

One of the biggest problems of proc. macros in Rust is that they do not allow to access the underlying types but only syntax. This has led us to design the current static storage allocations during run-time of a contract through the AllocateUsing trait. The consequences are that we have to repeat this step for every contract instantiation and contract call which is a waste of compute power and also increases the final resulting Wasm binary because it has to include all the computations for this process.

From what we can tell the computations required are most often very cheap, however we still consider them wasteful and especially for bigger contract with many different static storage entities this might no longer be true since it is work being done for every contract call.

This wastes:

  • Binary Size: Since runtime routines for static allocation have to be included into the final Wasm binary.
  • Gas: Since we have to perform this computation all over for every contract instantiation and call which is pretty wasteful.

Conclusion: We should really try as hard as possible to get rid of this up-front computation.

Potential Solutions

Solution A: Using some const_fn and const_generics hacks

For our purpose there are const_fn and const_generics on the horizont with which we might be able to emulate a similar system as what we are currently doing through AllocateUsing trait. It has yet to be found a proper design for this though.

Solution B: Using type metadata

We already generate contract metadata and thus type metadata while compiling a smart contract. We could theoretically reuse the information gained there and read the file during proc. macro execution. Using this approach we could have deep knowledge of the underlying types used. The downside of this approach is that we always need to generate metadata before we can do the actual compilation of the contract. This also counts for every substantial change to the contract.

Since we already encode the static storage parts in our contract metadata we could simply read out that portion of the metadata and "simply" convert that into static code. The biggest problem with this solution is to find a proper interface to instantiate the static contract storage completely at compile-time given all the type and key information by the metadata.


We dedicate this issue thread in order to find a potential and implementable solution for this major bottleneck and problem.

@Robbepop Robbepop added B-enhancement New feature or request A-ink_lang [ink_lang] Work item labels Nov 17, 2019
@Robbepop
Copy link
Collaborator Author

In #311 we dropped this idea and instead try to make those computations as cost efficient as possible using proper abstractions. Maybe in the future we can reiterate on the idea of shifting all computation to compile-time but with the current set of Rust features this is deemed to be not possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant