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

NEP-485: Shared Ephemeral Storage #485

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Changes to the protocol specification and standards are called NEAR Enhancement
| [0399](https://github.com/near/NEPs/blob/master/neps/nep-0399.md) | Flat Storage | @Longarithm @mzhangmzz | Review |
| [0448](https://github.com/near/NEPs/blob/master/neps/nep-0448.md) | Zero-balance Accounts | @bowenwang1996 | Final |
| [0455](https://github.com/near/NEPs/blob/master/neps/nep-0455.md) | Parameter Compute Costs | @akashin @jakmeier | Final |
| [0485](https://github.com/near/NEPs/blob/master/neps/nep-0485.md) | Shared Ephemeral Storage | @jakmeier @encody @firatNEAR | Draft |

## Specification

Expand Down
102 changes: 102 additions & 0 deletions neps/nep-0485.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
NEP: 485
Title: Shared Ephemeral Storage
Authors: Jakob Meier <@jakmeier>, Jacob Lindahl <@encody>, Firat Sertgoz <@firatNEAR>
Status: Draft
DiscussionsTo: https://github.com/near/NEPs/pull/485
Type: Protocol
Version: 1.0.0
Created: 2023-06-17
LastUpdated: 2023-06-17
---

## Summary

This proposal introduces shard-locally shared contract code, which enables accounts to refer to contract hashes of deployed contracts that live in a special storage called Shared Ephemeral Storage (SES). SES has no storage staking cost.

Data in SES is shared among every account on the same shard. It has a limited lifetime before it is deleted, but everytime it is accessed, its lifetime is extended. Contracts can modify the state of the account; this state is not shared. Only code is shared, not the data.

The key for data in SES is the hash of the value. This makes it immutable and allows users to trust that the shared code is never modified.

## Motivation

- Certain basic functionality contracts such as dead man switch or multi-signature contracts require ~1 NEAR just to cover the storage staking. If a user is using zero-balance accounts and meta-transactions to cover costs, it is highly likely that they wouldn't have any NEAR on their accounts.

- There are certain proxy contracts that are repeatedly deployed to different accounts for certain apps to function. One example is KeyPom, which deploys a contract costing 0.4 NEAR as a proxy contract for all of the trial accounts. This is not sustainable for businesses or individual users.

As this is a part of the [Account Extensions upgrade](https://github.com/near/NEPs/issues/478), some of the benefits of account namespaces are realized in conjunction with other proposals from the upgrade:

- Contract namespaces (submodules) can reference SES code, enabling easy and cheap contract composability.

## Specification

### The `SES` Trie Key

We introduce a new trie key: `SES`. It maps code hashes to epoch IDs. This defines when the code "expires" and is updated to "current_epoch +2" every time the code is accessed.

### The `SES` RocksDB Column

The contract code itself lives in a separate RocksDB column, which must also be synced during state sync.

### `DeployContract` action

The `DeployContract` action is modified to include a flag named `is_ses` that would deploy the contract to SES. The effect of this flag is that the contract code is not stored in the account's storage, but in the `SES` column instead, and the SES code is referred to by the receiving account as its deployed contract code.

The cost to deploy to SES is the same as deploying a contract normally.

### RPC view calls

#### `view_account`

The `view_account` call now also returns a field called `shard_id` that reveals which shard the account lives on.

#### `view_code`

The `view_code` call returns the SES code just as it would return the code of a normally-deployed contract. A new field, `is_ses`, is also introduced, containing a boolean value indicating whether the code is stored in SES.

## Reference Implementation

- WIP

## Security Implications

- When SES code expires, it is deleted, rendering every referent soft-locked. The soft lock is resolved when any account referencing the code re-deploys it. The re-deploy must be of identical code to the same shard ID.

## Drawbacks

- Exposes sharding to developers.
- Code expires.
- More complicated `DeployContract` action.

## Unresolved Issues (Optional)

- How long should the code live in SES before it expires?
- How would SES integrate with dynamic sharding?
- What happens when you `FUNCTION_CALL` a SES contract that references expired code?
Comment on lines +73 to +75
Copy link

Choose a reason for hiding this comment

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

Could you clarify/outline the motivation for expiring contract code (why expiring is needed, and what are the alternatives) ?

Copy link
Author

Choose a reason for hiding this comment

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

If the code doesn't expire, there's no guarantee that its storage will be paid for, but the validators are still required to keep it alive.


## Alternatives

- Hereditary "pinned" sub-accounts: when a sub-account is created, we add a flag (e.g. `pin`), which locks the sub-account to the same shard as the parent. The child can then reference code deployed by the parent by hash, similarly to the SES model described by this NEP. This version does not explicitly expose sharding, but it does severely limit which accounts are eligible to use the shared code storage.

## Future possibilities

See [the Account Extensions upgrade master issue](https://github.com/near/NEPs/issues/478).

## Changelog

### 1.0.0 - Initial Version

#### Benefits

- Cheaper contract deployments. With zero-balance accounts, preexisting contracts could even be deployed (and composed, to some extent) for free.
- Well-known/official/audited/standard/etc. contracts can be deployed to all shards and used without fear of, for example, a developer compiling them incorrectly, or them being tampered with in some other way.

#### Concerns

## References

- https://docs.google.com/document/d/1fQvNrhk5Lnfu_89qRBtosJlTYFRgFCgicqf5iKdeq8w/edit?usp=sharing

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).