Ethereum Storage Rent: What should we expect?
Blockchain rent in Ethereum has been a topic of discussion since at least 2015, and quite fruitfully so: several methods of implementing rent were designed. However, since then the talks have died down, mostly because Ethereum state size was not an issue at that time and there were more important optimizations to attend to.
The discussion was rekindled in November 2018, when a new roadmap for short-term Ethereum scalability (dubbed Ethereum 1.x) surfaced. The scalability improvements are set to arrive in 2019 and the Ethereum ecosystem is uncertain of what to expect.
This post aims to clarify the design and motivation behind blockchain rent for all concerned. The preliminary requirement for the material is knowledge of some blockchain and Ethereum basics. If you have a high-level understanding of how blockchain works, what gas is, and how it charged, it should be quite accessible.
Why do we need blockchain rent?
Discussions around curbing blockchain and state growth are not exclusive to Ethereum — they started as soon as the first years of Bitcoin and were one of the central topics in the Bitcoin vs. Bitcoin Cash debate.
Rapid growth of space requirements (for example, Bitcoin would need 24 Gb blocks to rival VISA) can lead to “household nodes” becoming non-existent — fewer owners would be comfortable allocating terabytes of space for free, even if their initial motivation to install a node was ideological. This would result in only powerful corporate/nation-state nodes being able to satisfy the growing requirements, leading to centralization and making the network a more cumbersome variant of traditional centralized solutions. Because of this, any substantial scaling through naive block size increases leads to centralization and countermeasures need to be designed to avoid that.
This leads us back to Ethereum 1.x. One of the key points of the proposed roadmap are some recently discovered optimizations in Ethereum clients that allow to reduce block propagation time and, consequently, increase block gas limit without increasing a number of uncle blocks, which destabilize the network.
However, there is still an issue of blockchain and state growth, which will accelerate proportionally to the gas limit increase. And this is where blockchain rent comes in. Economically incentivizing the developers to free-up space that is no longer needed can help slow down state growth and even possibly reduce its overall size immediately after activation, if older unused contracts are salvaged.
Also, despite being an additional headache for developers, blockchain rent can actually reduce fees for them, if they manage to free-up state in time.
How does it work now?
Persistent memory in Ethereum is called storage — the data written there, which constitutes both the code of the contract and its state, remains between calls, and nodes have to store it.
A special opcode to write 32 bytes (a “word” in Ethereum specification) into storage is SSTORE, and currently it costs 20000 gas if new slot is filled, or 5000 gas if a value is changed in an existing slot.
One can also set a slot value to zero to free it up (or use STORAGEKILL), and receive a refund of 10000 gas. It is important to note, though, that gas isn’t backward-convertible to Ether — if one wants to utilize the refund, they have to either spend it during the same transaction or bundle their transaction with another that will in turn consume that gas.
The main issue with the current system is that it does not incentivize developers to free-up space after a short time. There is no refund fall-off through time, and utilizing the refunded gas requires additional work to set up, so for most developers it simply isn’t worth the effort.
There are also some unpleasant externalities:
- Firstly, the current mechanism is path-dependent — even if you delete all the data you’ve written inside the same block, you will still pay an amount that is proportional to the number of writes, while with blockchain rent you will pay nothing, because time of storage is taken into consideration. A partial solution to this issue was proposed in the Constantinople update, but the corresponding EIP was disabled after a vulnerability was found.
- Secondly, it is currently possible for the miners to perform gas price arbitrage by saving junk into storage and then releasing it during congestion periods if gas price has risen more than 2x. There is even a project called GasToken that provides a nifty Ethereum contract to do so. The negative here is that full node owners have to store all that junk data in their state.
Proposed payment mechanisms
To implement blockchain rent, a number of design choices have to be considered. The first and the biggest element of design is the payment method. There are three methods that have primarily gained traction.
Direct payment per word-block. The most straightforward scheme was the first one proposed — a mechanism where a contract account is charged some amount each time someone makes a call, depending on the number of words stored and time elapsed since last call. The payment is calculated as
where TOTFEE(n) is a cumulative fee dependent on block number. It can be set to something as simple as TOTFEE(n)=cn, or it may be a more complex function — for example, if we want a 5 GB restriction on total state size, we can make the fees rise exponentially as state size nears this threshold.
The advantages of this mechanism are its simplicity and the fact that there’s no need for explicit refunds. The developers are simply incentivized to free-up storage so that they don’t have to pay unnecessary fees further. However, it needs an explicit deletion scheme, which is a tricky design challenge for a number of reasons (see below).
There is also a special type of attack on this mechanism called dust griefing attack, where an attacker may do arbitrary token transfers to new addresses to increase storage rent for the contract forever, at a relatively small cost to herself. Although it is specific to token contracts only, ERC20 tokens are essential to the current Ethereum ecosystem, which makes this attack an important issue. Here are some metrics to consider — ERC20 currently constitute 53% of total state and more than a third of total state are taken up by balances.
Despite these challenges, this payment method was the primary one considered for implementation in the latest version of rent proposal.
Exponential refund. The second mechanism takes a different approach — instead of charging some amount per time elapsed, it charges “a fee for owning the slot forever” at the time of write, and when the slot is freed, the remainder is returned.
If the initial paid amount is F, then the refunded amount is
where B and B0 are current block and the block of the initial write respectively, and I is some discount rate we set to regulate the speed of decay.
For an intuition, consider the price of a stock — it represents the sum of dividends paid to the owner each year, discounted with some cost-of-capital rate. Barring changing dividend expectations, if you sell the stock after 2 years, you will receive the new price with dividends for those 2 years subtracted. The logic behind this mechanism is the same, although instead of dividends you consume value through storage use.
There is an issue with implementing this model as-is — we have to store time of creation for each active slot in the storage, which is a considerable overhead. To circumvent that, we can instead use a sort of average-cost accounting: instead of tracking the initial block per-slot, track the “last accessed” block T and a total deposit per-account D, and after clearing the slot the deposit is set to
while D/S (after reducing the deposit) is refunded. This heuristic produces the same result on average and reduces the overhead from per-slot to per-account.
The downside to this mechanism is that, to provide ample incentive for cleaning up, F should be sufficiently big — substantially bigger than current per-write fee. Such a change could lead to “get it while it’s cheap” mentality and massive hoarding before the update, followed by dark rent markets.
However, the colossal advantage is that it is extremely backward-compatible — it doesn’t require an explicit deletion mechanism, and implementing fees comes down to implementing dynamic pricing for SSTORE and STORAGEKILL. This feature makes the mechanism a prime candidate for immediate implementation in Ethereum 1.x.
Pseudo-random sampling. This last mechanism is interesting and easy to understand, but hasn’t gained a lot of traction because it relies on pseudo-random sampling, which is a yet-to-be-solved problem in Ethereum.
In this mechanism a contract gets a second balance called “lease”. There is also a system-wide parameter “rent”, which can be regulated in a same manner as the gas limit. On each block, we choose a set of accounts to be charged pseudo-randomly with probabilities proportional to their fraction of total storage.
If the account does not possess enough funds in its lease balance when miners try to charge it, it deleted or archived.
With this payment model it’s fairly easy to calculate your average rent costs, although one has to consider an always non-zero chance of default. It’s also backward-compatible — all new values can be assumed to always have been zero.
However, the required pseudo-randomness is not implemented yet, and is unlikely to be implemented very soon, so this mechanism is something that would probably be explored in Serenity.
Ether vs. Gas
Another important variable is currency in which the fees are paid. There are some advantages and disadvantages to using Ether and to using Gas.
If we use Ether, it becomes easier to decouple economics of computation fees and storage fees. Currently, if the network is congested and the price of computation is high, storage also becomes expensive, which is suboptimal. With Ether fees we can introduce a pricing mechanism tailored specifically to the task of charging for storage. This would also introduce an additional source of utility demand for Ether — while they are unlikely to be considerable at first, in the future storage costs may grow large enough to increase and stabilize the price.
However, an Ether-denominated fee requires more consensus-level changes to implement, and also needs an explicit price discovery mechanism. This complexity makes Ether-based fees less suitable for Ethereum 1.x simply from implementability and backward-compatibility standpoints.
Conversely, with gas it’s much easier to reconcile the new mechanism with older systems — price discovery is already present and introducing storage rent may amount to calculating prices/refunds for SSTORE and STORAGEKILL dynamically. However, the aforementioned gas price arbitrage externality remains, and the refunded gas is harder to utilize, because it has to be used immediately in other transactions.
If a payment scheme requires contract deletion, we also want to implement some resurrection protocol, so that, for example, long-term lock-up contracts aren’t lost.
The current proposal is to leave a receipt in the blockchain each time the contract gets deleted, which later can be used to resurrect the contract with its state unchanged.
However, there are some unsolved design challenges with deletion and resurrection:
- Firstly, this resurrection scheme may be exploited if the contract were destroyed twice — the attacker can present the older receipt and, thus, revert contract state. To solve this, a system was proposed where someone can challenge contract resurrection by presenting a more recent receipt. However, such system would require major changes to protocol, and incentive of challengers must also be designed.
- Secondly, contract deletion in general leads to a freerider-like problem with public contracts — while there is a centralized developer, they will likely maintain the contract and ensure it has enough funds for rent, but for contracts with no explicit owner it is unclear who should pay. Some recent advances, such as Liberal Radicalism distribution system, may help in that regard, but it is an open topic.
Who receives the payment?
The final design choice we have to make is how the accumulated funds are distributed.
Naturally, we want to distribute them among full nodes, but the only full nodes we can reliably verify are miners. There already concerns over great concentration of Ether in miners’ hands, which can lead to collusion and 51% attacks in Serenity. Giving miners an additional source of income would likely exacerbate the problem.
The method that is likely the most popular right now is simply burning the collected Ether, creating deflation. It is certainly the simplest, however, at the current stage of Ethereum ecosystem the deflation would likely be “crowded-out” by speculative price movements. This does, however, seem an effective measure of redistribution in a mature network with stable Ether and high storage use, so it seems to be the best model for Serenity.
Blockchain rent caused a bit of panic in the Ethereum community in the last couple of months. With this post, we wanted to familiarize all concerned with the current state of discussion and give some definitive notion of what to expect.
If you have your own ideas on mechanisms and techniques that could make blockchain rent more socially useful and friendly to Ethereum users, we urge you to join the discussion at Ethresearch or Ethereum Magicians.