From 191789e8aa36c51f07f22c31f06f7db2126ce697 Mon Sep 17 00:00:00 2001 From: Jacob Lindahl Date: Sat, 17 Jun 2023 00:54:12 +0900 Subject: [PATCH 1/3] add SES initial draft --- neps/nep-0000.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 neps/nep-0000.md diff --git a/neps/nep-0000.md b/neps/nep-0000.md new file mode 100644 index 000000000..83431b719 --- /dev/null +++ b/neps/nep-0000.md @@ -0,0 +1,105 @@ +--- +NEP: 0 +Title: Shared Ephemeral Storage +Authors: Jakob Meier <@jakmeier>, Jacob Lindahl <@encody>, Firat Sertgoz <@firatNEAR> +Status: Draft +DiscussionsTo: https://github.com/near/NEPs/pull/0000 +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 conracts that live in a special storage called Shared Ephemeral Storage (SES). SES has no storage staking cost. + +Data in SES is shared between every account on the same shard. It has a limited lifetime before it is deleted. But everytime it is accessed, the lifetime is extended. +Note: 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 the shared state is not unexpectedly mutated by someone else. + +## Motivation + +- Certain basic functionality contracts such as `Dead Man Switch` or `Multi-Sig` contracts require ~1 NEAR just to cover the storage staking. If a user user is using zero-balance acccounts 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 deployed over and over again on different accounts for certain apps to function. One example is Keypom, where for trial accounts to work, `0.4N` contract has to be deployed 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: + +## Specification + +### The `SES` TrieKey + +We introduce a new TrieKey: `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. + +### 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_state` + +The `view_state` call now accepts an optional `namespace` field. If it is not specified, the default namespace is used. The `view_state` call is then executed on the state associated with the specified namespace. + +#### `view_code` + +The `view_code` call now accepts an optional `namespace` field. If it is not specified, the default namespace is used. The `view_code` call then returns the code deployed on the specified namespace. + +## Reference Implementation + +- https://github.com/near/nearcore/pull/8890 + +## Security Implications + +- Applications that detect smart contract updates by tracking the `code_hash` field from a `view_account` call will fail to account for updates to namespaces. (Note that the correct way to track code changes is by monitoring the blockchain for `DeployContract` actions targeting the account, not by tracking `code_hash`.) +- As described by this NEP, namespaces all have full permission to act on behalf of the account, just as any smart contract. +- If a namespaced contract interacts with a legacy contract (unaware of namespaces), it is possible that the legacy contract may save the account ID of the namespaced contract, but not the namespace. If the legacy contract subsequently attempts to interact with the namespaced contract, it will only be able to interact with the contract deployed to the default namespace instead. However, this is equivalent to the case in which an non-contract account signs the same set of actions to the legacy contract. + +## Drawbacks (Optional) + +## Unresolved Issues (Optional) + +- How to delete a namespace? +- How to enumerate namespaces from within a smart contract? +- Backwards compatibility issues could be resolved with a per-account routing table that maps incoming method names to a [namespace, method name] pair. + +## Alternatives + +- Only using a routing table. However, this increases complexity for end-users significantly. + +## Future possibilities + +- Sync execution between namespaces. +- Permissioned namespaces. +- Codeless contracts / contract subscriptions / global contracts. + +See [the Account Extensions upgrade master issue](https://github.com/near/NEPs/issues/478). + +## Changelog + +### 1.0.0 - Initial Version + +#### Benefits + +- Easier contract composability, e.g. just deploy the NEP-141 and NEP-330 modules and you’re set. Good for developers (esp. w.r.t. contract factories) and non-developer users (one-click deploy composable modules). +- Safer and easier contract upgrades, e.g. have an upgrade_controller namespace that manages upgrading the rest of the contract’s components, so a bad upgrade doesn’t brick the account. + +#### Concerns + +## References + +- https://gov.near.org/t/proposal-account-extensions-contract-namespaces/34227 + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From c432cd126e6381651e83fa9718dbc708613aa84a Mon Sep 17 00:00:00 2001 From: Jacob Lindahl Date: Sat, 17 Jun 2023 00:56:20 +0900 Subject: [PATCH 2/3] use nep number --- README.md | 1 + neps/{nep-0000.md => nep-0485.md} | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename neps/{nep-0000.md => nep-0485.md} (98%) diff --git a/README.md b/README.md index 6b81d1867..9f4daf8f6 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/neps/nep-0000.md b/neps/nep-0485.md similarity index 98% rename from neps/nep-0000.md rename to neps/nep-0485.md index 83431b719..f3800dc49 100644 --- a/neps/nep-0000.md +++ b/neps/nep-0485.md @@ -1,9 +1,9 @@ --- -NEP: 0 +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/0000 +DiscussionsTo: https://github.com/near/NEPs/pull/485 Type: Protocol Version: 1.0.0 Created: 2023-06-17 From ac09ff62f2273745b90ec572011019a01d2eace6 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 20 Jun 2023 12:56:55 +0900 Subject: [PATCH 3/3] clarifications, fix some typos --- neps/nep-0485.md | 57 +++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/neps/nep-0485.md b/neps/nep-0485.md index f3800dc49..5a40e67a3 100644 --- a/neps/nep-0485.md +++ b/neps/nep-0485.md @@ -12,26 +12,27 @@ LastUpdated: 2023-06-17 ## Summary -This proposal introduces shard-locally shared contract code, which enables accounts to refer to contract hashes of deployed conracts that live in a special storage called Shared Ephemeral Storage (SES). SES has no storage staking cost. +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 between every account on the same shard. It has a limited lifetime before it is deleted. But everytime it is accessed, the lifetime is extended. -Note: Contracts can modify the state of the account, this state is not shared. Only code is shared. Not the data. +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 the shared state is not unexpectedly mutated by someone else. +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-Sig` contracts require ~1 NEAR just to cover the storage staking. If a user user is using zero-balance acccounts and meta-transactions to cover costs, it is highly likely that they wouldn't have any NEAR on their accounts. +- 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 deployed over and over again on different accounts for certain apps to function. One example is Keypom, where for trial accounts to work, `0.4N` contract has to be deployed as a `proxy-contract` for all of the trial accounts. This is not sustainable for businesses or individual users. +- 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` TrieKey +### The `SES` Trie Key -We introduce a new TrieKey: `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. +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 @@ -39,7 +40,9 @@ The contract code itself lives in a separate RocksDB column, which must also be ### `DeployContract` action -The `DeployContract` action is modified to include a flag named `is_SES` that would deploy the contract to SES. +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 @@ -47,42 +50,36 @@ The `DeployContract` action is modified to include a flag named `is_SES` that wo The `view_account` call now also returns a field called `shard_id` that reveals which shard the account lives on. -#### `view_state` - -The `view_state` call now accepts an optional `namespace` field. If it is not specified, the default namespace is used. The `view_state` call is then executed on the state associated with the specified namespace. - #### `view_code` -The `view_code` call now accepts an optional `namespace` field. If it is not specified, the default namespace is used. The `view_code` call then returns the code deployed on the specified namespace. +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 -- https://github.com/near/nearcore/pull/8890 +- WIP ## Security Implications -- Applications that detect smart contract updates by tracking the `code_hash` field from a `view_account` call will fail to account for updates to namespaces. (Note that the correct way to track code changes is by monitoring the blockchain for `DeployContract` actions targeting the account, not by tracking `code_hash`.) -- As described by this NEP, namespaces all have full permission to act on behalf of the account, just as any smart contract. -- If a namespaced contract interacts with a legacy contract (unaware of namespaces), it is possible that the legacy contract may save the account ID of the namespaced contract, but not the namespace. If the legacy contract subsequently attempts to interact with the namespaced contract, it will only be able to interact with the contract deployed to the default namespace instead. However, this is equivalent to the case in which an non-contract account signs the same set of actions to the legacy contract. +- 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 -## Drawbacks (Optional) +- Exposes sharding to developers. +- Code expires. +- More complicated `DeployContract` action. ## Unresolved Issues (Optional) -- How to delete a namespace? -- How to enumerate namespaces from within a smart contract? -- Backwards compatibility issues could be resolved with a per-account routing table that maps incoming method names to a [namespace, method name] pair. +- 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? ## Alternatives -- Only using a routing table. However, this increases complexity for end-users significantly. +- 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 -- Sync execution between namespaces. -- Permissioned namespaces. -- Codeless contracts / contract subscriptions / global contracts. - See [the Account Extensions upgrade master issue](https://github.com/near/NEPs/issues/478). ## Changelog @@ -91,14 +88,14 @@ See [the Account Extensions upgrade master issue](https://github.com/near/NEPs/i #### Benefits -- Easier contract composability, e.g. just deploy the NEP-141 and NEP-330 modules and you’re set. Good for developers (esp. w.r.t. contract factories) and non-developer users (one-click deploy composable modules). -- Safer and easier contract upgrades, e.g. have an upgrade_controller namespace that manages upgrading the rest of the contract’s components, so a bad upgrade doesn’t brick the account. +- 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://gov.near.org/t/proposal-account-extensions-contract-namespaces/34227 +- https://docs.google.com/document/d/1fQvNrhk5Lnfu_89qRBtosJlTYFRgFCgicqf5iKdeq8w/edit?usp=sharing ## Copyright