Iterators and prefix deletions #159
Replies: 4 comments 6 replies
-
Just as a suggestion how to implement the collection where subset can be deleted without adding too much overhead:
|
Beta Was this translation helpful? Give feedback.
-
Let me address the challenges/state witnesses down below. First, I would like to emphasize that keeping a simple state interface is potentially an even more important argument than the argument about challenges/state witness. Minimal State InterfaceI would classify all key-value interfaces into: minimal and extended. Minimal key-value interfaces only allow random key-value lookup/read/write/deletion. Extended key-value interfaces additionally have features like: iterators, range queries, prefix-based operations. With blockchain, once we allow contracts that use features of extended key-value interfaces, we cannot remove these features ever, because contracts are the only permanent non-upgradable thing on the blockchain (with few very specific exceptions, like staking pools). We would like to reserve an opportunity to change our state design in the future, and potentially move from MPT to AVL trees, Urkel, or variations of binary trees that @abacabadabacaba has in mind. This will allow us to greatly increase TPS on a single shard improving our core value proposition. Unfortunately, extended key-value interface can prohibit us from iterating over the state design.
Besides performance there are other reasons to switch from MPT, e.g. we don't want shard users to be able to manipulate the MPT depth and cause extreme fee cost to some contracts (e.g. a competitor exchange). AVL tree, for example, would prevent such abuse as suggested by @abacabadabacaba . While having extended key-value interfaces is undoubtedly convenient for the contracts, I don't think this convenience justifies missing a potential opportunity to drastically increase our TPS in the future, or being able to have non-abusable state structure. Challenges/state witnessesSuppose a validator X receives a challenge from validator Y about chunk on shard A being incorrectly produced. Validator wants to check the validity of the challenge without downloading the state of shard A, so it relies on "state witness" (a subset of state) attached to the challenge to validate the claim of incorrectness. As validator X is verifying the state there could be only two possibilities:
Suppose chunk contains contract execution that iterates over the keys prefixed with
Unfortunately, from the perspective of validator X the above two use cases are indistinguishable so it does not know whether to slash the chunk producer or to reject the challenge. This however, is not fundamentally unsolvable problem. In case of prefix iterators, we can require challenges to always include one more node that comes next after the iterator stops, which should be sufficient for the challenge to be self-verifiable. However, this adds complexity to the challenges, because it will require careful special-casing in PartialStorage implementation, and any incorrectness will lead to the wrong user being slashed. Other extended operations, like prefix deletion, might require their own special-casing, which will increase the complexity further. Proposed approachIt seems like the main motivation for prefix-deletion is about reducing the cost of Ethereum contract deletion in EVM so that it is as low as other NEAR EVM operations. However, I think at the beginning, the primary metric by which people will judge NEAR EVM performance will be contract deployments, standard contract calls, and not contract deletions. We can shelve this problem, until we settle with a new state design in 1+ year from now. For now we can either emulate prefix-deletion either the way near-sdk-rs emulated iterators or using linked hashmap that @ilblackdragon proposed but inside Wasm. This will increase the cost of deleting Ethereum contracts in EVM, but it won't matter for most of the contracts. Once we settle with new permanent state design, we can upgrade Wasm part of NEAR EVM to use native prefix deletion instead of emulation (assuming the new state design will allow prefix-deletion primitive). |
Beta Was this translation helpful? Give feedback.
-
I will post here a proposal that I had during EVM work group, regarding the way we can implement contract deletion in EVM without relying on iterators. I am assuming that each EVM storage entry is mapped to a NEAR storage entry. In that entry's value, I propose to store generation number in addition to the Ethereum value. This number is initially zero, but is incremented each time a contract is redeployed at the same address (which is possible by using CREATE2 opcode). Only the entries with the current generation number are considered when accessing the storage. We may optionally add a function that anyone may call to purge the stale entries and reclaim the storage stake. |
Beta Was this translation helpful? Give feedback.
-
Performance. Currently some things already take 100 Tg (for still unclear
reason to me), so if we also hit a bit deletion process it may not fit into
a single action limit.
…On Sun, Feb 21, 2021 at 3:25 PM Maksym Zavershynskyi < ***@***.***> wrote:
This adds extra game-theoretic level to EVM with actors claiming storage.
What is the reason for not modeling prefix deletions like we do in
near-sdk-rs or using linked hashmap implemented in Wasm?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#159 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABK27T5QI5MQN6CR6FZCULTAGI7FANCNFSM4X32K6PA>
.
--
Best regards,
Illia Polosukhin
|
Beta Was this translation helpful? Give feedback.
-
We have had iterators in the runtime before but it was deprecated and removed.
The main reasoning at the time was that there is no way to create a challenge state data structure.
I'm honestly still lost there why that is so, and would like to get this reasoning recorded here for future reference.
Let's say there are items in the collection are ["xxx1", "xxx2", "xyy1", "xz"] and there is a prefix iteration over "x" items that get stopped after 2 elements. My understanding is that the concern is that one can pretend that the collection has only ["xxx1", "xxx2"] elements which the program did iterate over.
But generating a stateless proof for that will not work, as the merkle path would not be the same.
Separately, I think prefix deletion is pretty useful primitive - from implementing migrations (removing an old collection) to managing more advanced collections (like what EVM contract is doing). Prefix deletion doesn't require anything specific on the stateless challenge side - as it's just requires path from root to the common suffix and replacement of item in the branch.
Beta Was this translation helpful? Give feedback.
All reactions