Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

seal: Storage rent for code #6596

Closed
@athei

Description

@athei
Member

Currently, no rent is collected for code that is stored on-chain. Only the state of the individual contracts is subject to rent payments. This is because code is deployed independently of a contract and can then be used by any contract without further costs. There is also no way (apart from governance) to remove code stored on the chain.

This opens up the chain to DoS because anyone can clutter the storage with code with only a one time cost that covers the computation costs of uploading the code.

For that reason, we propose that contracts should pay for the code they use. To incentives code sharing the costs are also shared between all users of a code blob. We change the rent formula that is calculated on contract access or claim_surcharge to:

rent = storage_rent + (code_size / num_code_users)

The costs for code storage converge against zero with more users using it. Due to integer arithmetic is reaches zero once num_code_users > code_size.

One issue is that the rent is not collected every block but only when the contract is accessed or claim_surcharge is called. The num_code_users can change in between blocks making the calculation inaccurate. However, we argue despite the inaccuracy we cannot come up with an attack that turns this into a DoS vector.

Steps that are necessary for implementation:

  • Count the number of users per code hash and delete the code hash once the counter reaches zero
  • The set_code dispatchable is replaced with instantiate_with_code because every code_hash needs at least one user. The seal_instantiate contract callable function stays untouched. Contracts cannot deploy code.
  • Change the rent formula of contracts to also account for the code size.

Activity

added
I2-securityThe client fails to follow expected, security-sensitive, behaviour.
on Jul 7, 2020
Robbepop

Robbepop commented on Sep 28, 2020

@Robbepop
Contributor

Naming proposal:

seal_instantiate -> seal_instantiate_from
seal_put_code -> seal_instantiate

seanyoung

seanyoung commented on Sep 28, 2020

@seanyoung

At some point in the future, it would be great to have libraries stored on chain. For example, a wasm dynamic linked library could be available as code. Maybe we seal_instantiate doesn't make much sense in this context.

athei

athei commented on Sep 28, 2020

@athei
MemberAuthor

Those would get an additional set of interface functions anyways. Alone for the reason that we can't change the semantics of existing interface functions once deployed.

In order to make sure that someone pays for the code of the shared lib we would add a function that supplies two code blobs: The code of the lib and the code of a contract that is its first user. The latter code would be automatically instantiated and that is the contract that pays rent for both the lib and its own code. Adding more users of that lib though seal_instantiate_from or seal_instantiate would then distribute the rent costs among all users.

athei

athei commented on Oct 25, 2020

@athei
MemberAuthor

Naming proposal:

seal_instantiate -> seal_instantiate_from
seal_put_code -> seal_instantiate

This rename would change the semantic of an existing name. I don't want to cause confusing and code churn by doing so. Keeping seal_instantiate the way it is, is my only condition. By doing so we do not have to touch host functions in any way right now because there is no host function that can deploy new code. We can add this later if it turns out that contracts want to generate new contract code but this is an entirely different topic.

I would just replace the put_code dispatchable with a new function. Ideas:

instantiate_with_code
instantiate_with_upload
instantiate_uploading
Robbepop

Robbepop commented on Oct 25, 2020

@Robbepop
Contributor

How about instantiate_new?

athei

athei commented on Oct 25, 2020

@athei
MemberAuthor

I did not consider that because it is misleading: It is not guaranteed that the instantiated code is new. If you upload a code and the code hash already exists this existing code will be used.

ghost closed this as completedin #7935on Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    I2-securityThe client fails to follow expected, security-sensitive, behaviour.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @seanyoung@athei@Robbepop

      Issue actions

        seal: Storage rent for code · Issue #6596 · paritytech/substrate