header-langage
简体中文
English
Tiếng Việt
Scan to Download the APP
Partnered With:

Opinion: Eth2 as a Data Availability Engine

Read this article in 16 Minutes
The author intends to propose a roadmap to replace Phase 2 for Eth2.0, that is, if only sharding is used to ensure data availability, is such a system useful.
Original title: "View | Phase one and done: Eth2 as a data availability engine"
Original source: Ethereum Enthusiast



Editor's Note: The original title of this article was "Phase One and Done: eth2 as a data availability engine". At the time of publication (April 2019), the author intended to .0 proposes a roadmap to replace Phase 2, that is, if only sharding is used to ensure data availability, is such a system useful, and what parts need to be added to make it useful. Surprisingly, a year and a half ago, the author had realized that for a system like zk-rollup, the bottom layer must guarantee that "the execution of state transitions and data availability must be atomically bound Together", so the bottom layer must have the ability to execute, even if it is a very simple stateless execution; moreover, (the author also pointed out through layer-by-layer reasoning) to ensure the user experience, the main part that is still missing is the procedure of how to shard the data Fee payment agreement (these two points of understanding, even today, can still be called cutting-edge, even advanced). The fee protocol is still missing in the Phase 2 specification.


By the way, the author of this article is Casey Detrio, who is part of the Ewasm team and has also provided many ideas for Phase 2 before; Eth2.0 is designed with the core of "guaranteeing that Eth1 contracts can be executed as usual when Eth2 arrives". He is an underrated developer.


Currently, the bottleneck limiting Eth1 throughput is state growth. So, if we want to scale Ethereum, logically, 1000 shards with independent state can increase throughput by 1000 times.


However, from the Eth1.x route, Eth1.x wants to make major adjustments to the cost of two types of resources: storage (storage) and transaction data (tx data). Currently, storage is underpriced and transactional data is overpriced. This will incentivize dApp developers to use more storage than transaction data when writing contracts, causing storage to become a throughput bottleneck. The proposed solution to this problem is to increase the pricing of storage and decrease the pricing of transactional data. With these cost adjustments, developers will be incentivized to use transaction data more than storage (i.e., they will write more stateless contracts instead of stateful ones). Therefore, in the near future (if the Eth1.x roadmap achieves widespread adoption), we expect Eth1 throughput to be limited by transaction data rather than storage.


If we assume that throughput is bounded by transaction data, then shards on Serenity do not need to be stateful in order to scale Ethereum. If throughput is limited by transaction data from stateless contracts, then 1000 stateless shards will increase throughput by 1000x.


This sounds good, but it needs to be implemented through sharding, which is planned to wait until Phase 2. At the same time, we can use Phase 1 as the data availability engine. The term data availability engine seems to be gaining popularity. Let's think about how it works.


Take zk-rollup as an example, zk-rollup is limited by data availability. Can a zk-rollup contract on Eth1 effectively use Eth2 as a bridging availability guarantee provider? If data availability cannot be guaranteed during execution (i.e., verifying the SNARK proof and updating the state root), you end up with a plasma-like zk-rollback system. Although this system can greatly improve TPS, it will introduce complex trade-offs and need to deal with operator challenges and exit mechanisms like plasma. In an availability challenge, anyone can provide data to prove availability, so it's not clear that putting data into a bridged Eth2 shard would make things easier.


Now there is another version of zk-rollup, the 500 TPS zk-rollup, and everything is much simpler. There is no longer a need for a designated operator, anyone can act as a relay at any time and generate SNARK proofs to update the state. In fact, data availability guarantees are always accompanied by state updates, which means there is no need to deal with operator challenges and exit mechanisms like plasma. But this requires both execution and data availability to happen in the same transaction, which unfortunately we cannot do with a bridged availability engine. In other words, bridging is sufficient for a fraud proof system like zk-rollback, but not enough for a validity proof system like zk-rollup. The conclusion is that in order to simplify the validity proof on Layer 2, an important function that the availability engine on Layer 1 needs to have is to ensure that the availability of data and the execution of state transitions happen together atomically.


Perhaps we shouldn't be surprised by this realization. If data availability alone (without execution) was useful, no one would argue that Phase 1 started just to ensure the availability of a bunch of non-zero blobs (binary large objects), and no one would complain about having to wait for Eth2 to come in The next stage will really come into play (besides PoS). We're working on Phase 1 as the data availability engine, but it still doesn't do anything, so it's disappointing. (Wow, we can build Mastercoin 2.0!)


So why would Phase 1 conflict with implementation? Well, assuming stateful execution, each shard maintains some local state. Validator shuffle is much more complicated if validators need to maintain a lot of local state. Conversely, if there is no implementation, don't worry about local state. Validator shuffle would be much simpler, we could focus on building shards with data blobs, and start shards faster.


However, let's not assume that execution is stateful. What if we try to do it with a very simple stateless virtual machine?


Assume there are 3 new validator fields in the beacon chain state: code, stateRoot, and deployedShardId. There is also a function process_deploy (just below process_transfer). Once the code is deployed, the verifier must ensure that the account balance does not fall below a certain threshold [at least 1 ETH locked. If there is no self-destruct program (SELFDESTRUCT) in the code, then this part of ETH is equivalent to being destroyed, and the code will be permanently deployed].


Now, let's assume that there are already some accounts with code in the global state.


Next, we try to pack specific data blobs onto shards, but how? As far as I know, it is still an open question for phase 1 shard validators to decide which data blobs to pack into shard blocks. Assume this is not detailed in the phase 1 specification. Then, for users, if they want to pack their own data blobs into shards, there are only two ways: (1) contact the verifier, and send to Its payment; (2) Become a verifier yourself, and you can (when they are randomly selected as the block proposer of the shard) pack the data blob onto the shard. Both of these methods are bad ideas.


A better way is to put things on the table and allow the verifier to pay the current block proposer through a transaction agreement. In exchange, the block proposer packages the validator's data blob onto the shard chain. However, this approach does not work if beacon chain block operations (such as validator transfers) have minimum capacity requirements. The "phase 1 as data availability engine" use case would not be possible without a transaction protocol that would allow validators to prioritize data blob packing (whether it's an eth1 contract connected via a bridge to the beacon chain, or a Truebit , Mastercoin 2.0, or other data availability use cases I’ve heard of before). Anyway, let's assume that no matter how the shard proposer packs data blobs in the "Data Availability Engine without Execution" mode, it can be equally available in the "Data Availability Engine with Simple Stateless Execution" mode. do it.


Okay, so let's say that certain data blobs can be packed into blocks. Each block limits execution to one transaction (e.g. the entire data blob must be included as one transaction). We have not yet clarified whether the transaction will be signed with a key (there is a transaction agreement), or it will not need to be signed (there is no transaction agreement). Assume the latter, and the code implements its own signature checking (similar to an account abstraction; there is a block gas limit, but no fee transfer mechanism, so no gas price and no GASPAY opcode). If the blob can be successfully decoded as a transaction, the target account code is executed with the data and the current state root as input. If the execution is successful, the return data is the new state root.


How do we update the stateRoot of the validator account? We cannot update the state root in the BeaconState (beacon chain state) of each shard block (because the number of beacon chain operations is strictly limited). However, the fragmentation field in the state of the beacon chain will be updated with the crosslink. Take the updated state roots of all accounts on the same shard, and suppose they are hashed to get shard_state_root (shard state root). shard_state_root seems to be similar to the crosslink_data_root already in the phase 1 design (both depend on hashes of previous shard block contents).


It cannot be denied that not all shard state roots are updated every time a beacon chain block is mined, so there is some local state. However, if the account is global, the state root data is minimized. This is similar to the need to transfer some shard block data between validators during a shuffle.


Of course many details are ignored here. What I'm trying to convey is that most of the requirements for stateless execution seem to be met in phase 1. In my opinion, the biggest problem is that it is not yet clear how users can package their blobs on the chain (if this problem is not solved, phase 1 cannot be a bridge usability engine). Perhaps this is just the first problem, and there are other serious problems that I have overlooked. What am I missing? What is the hardest part about allowing users to somehow package blobs on-chain in phase 1 (or phase 1.1, if you like)?


This execution mode is simpler than the phase 2 proposal. One of the reasons is that the contract account is global, just like the validator account. This means that the number of contract accounts must be capped, and the cost of deploying the code is as high as (and possibly less than) the cost of becoming a validator. However, if this allows us to bring execution to Eth2 faster, is this a trade-off we can accept? After the code is deployed, the contract storage cannot be changed, so it can be said that we are trying to provide execution functions for Phase 1 without expanding the contract storage. There is another important use case here: ultra-high throughput with data availability (1000x increase in transaction throughput).


Even with basic stateless execution, users can send the state proof of one contract as transaction data to another contract to achieve cross-sharding Contract call. Contracts can also implement their own receipt-like functionality (receipts in the contract state root are as verifiable as receipt fields in block headers). The developer experience is not very good, because the agreement will not provide any help. But existing phase 2 proposals seem to lack practical features to facilitate cross-shard contract interaction (these troubles are left to dApp developers, who must implement the logic of obtaining receipts from different shards, ensuring receipts are not double-spend, etc.) . So basic phase 1 stateless execution doesn't sound much worse than a "simple" phase 2 idea in terms of developer experience. The underlying stateless execution is also sufficient for a two-way peg between BETH on the beacon chain and ETH on the main chain.


The biggest difference between the Phase 2 proposal and our proposal here is that the goal of Phase 2 is to expand the storage of the contract. But storage, and consequently stateful execution, also seems to be the source of most of the complexity, and it is what makes us hopeless to introduce execution in Phase1.


Original link



Welcome to join the official BlockBeats community:

Telegram Subscription Group: https://t.me/theblockbeats

Telegram Discussion Group: https://t.me/BlockBeats_App

Official Twitter Account: https://twitter.com/BlockBeatsAsia

举报 Correction/Report
Choose Library
Add Library
Cancel
Finish
Add Library
Visible to myself only
Public
Save
Correction/Report
Submit