Ethereum State rent for Eth 1.x pre-EIP document

storage-rent
eth1x

#15

One other random thought: how we actually pay the rent (specifically using the actor/asset model)

The naive way would be to have whatever ether balance an address has be the rent payment. This makes it easier to collect rent for “large, central contracts” – just send ether to that address and it gets deducted at a rate of storage costs. If it runs out, the storage gets archived, then removed after some period (only the root remains).

However, let’s say you want to hibernate your holdings (meaning you will accept the burden of storing the state tree entry matching the root that remains). Your holdings include some significant amount of ether that you don’t want drained as you go into hibernation. A way to do that in my mind might be to make use of “semi-fungible tokens” (related to ERC 1410) where Ether holdings can be split into 2 holding groups: rent payment balance and free (non-rent) holdings. This would help contracts who are programmed to deal with escrow of Ether not to get their balances mixed with the rent payment balance.


#16

I’ve noticed some focus on “mitigating GasToken” on other forums like ethresear.ch. Why is that? The point of GasToken is to save state and later clear it to get refunds when gas prices are high, so it’s unlikely to continue growing unbounded compared to other contract types.

I did not include this into the deck, but as it stands at the moment, abandoned contracts (those not used for the last 12 months) represent only 6% of the state.

Super interesting! From just eyeballing charts 1 and 2, it looks like total state was ~30% of current size 12 months ago. Is this right? So if 6% of current state is abandoned, that means 20% of the total state as of 12 months ago is now abandoned? That may suggest the 6% number will start growing dramatically in the coming months

Data owners should not be allowed to modify storage written by other contracts. But they should be able to withdraw that write permission, to stop paying for the store.

I’m guessing we would make a contract’s write permission all-or-nothing? E.g. assume a contract stores user balances and debts. If the user could withdraw permission for the debt-storage field, that would enable them to drain the contract.

But then is there also a token-dusting attack vector if a contract’s write permission is all-or-nothing? E.g. someone can send me dust from millions of tokens on EtherDelta which would make the rent prohibitively high. Unless we require authorization for each storage field used which seems like really complicated UX


#17

Adding another response here

Main reason not to go specifically after abandoned contract is the fact that a spiteful adversary can easily neutralise such measures, and it will wasted work.

Debt is not an assert of the debtor, but of the creditor. The creditor is the one who should keep it and pay for it. That way, debtor cannot clear away the debt.

It is not all-or-nothing. On the page 40, there is opcode XGROW, which owner can use to expand the cell writeable by a particular writer. Owner cannot shrink the cell though, only complete remove it


#18

Interesting line of thought. It might be possible to quite easily achieve that with a wrapped ETH token contract, which under the new model will have a constance storage size and can easily sustain itself by eating into the wrapped ETH it contains, or utilising callfee (page 48).


#19

In other words, “RentToken” lol


#20

CallFee and Linear cross-contract storage both seem like powerful abstractions. Are these things that you want to add to the base layer or do you think they can be implemented in the scripting language?


#21

To the base layer, as they require new opcodes and new consensus structures


#22

The issue with this is that you would have to know ahead of time how long you want to (to borrow your term) ‘hibernate’ said holdings, in order to ensure you purchase enough of the NFT’s to cover rent.

The obvious answer to this is to say that if the balance of the Rent NFT dwindles to zero, then there is a default to rent begining draw off the primary holdings. However, if this is, ultimately, where we default to, it may as well be where we start from as well.


#23

Comment from Reddit and my replies

Yes, users will need to do something to receive tokens. Because at the end of the day, they will pay maintenance for the space these tokens take. It would be wrong to allow anyone to burden you with such maintenance without your consent. On the other hand, it makes the fat finger problem less likely. Useless airdrops will not be possible. Tokens organised in such way will have better legal standing (this is my speculation)

EDIT: on the legal standing - in real world, you normally have an option to refuse unwanted gifts. And sometimes, it protects you from liability

Thanks for the comment! I shall explore this more in the next version of the document. It actually mentions what you are suggesting, on the page 23 under “alternative point of view”. Obviously, the greater is the min-value, the smaller is griefing factor. But the greater is the min-value, the smaller is number of owners who can potentially hold the token. Will try to put some numbers behind this - to make is more visible why I think it is a genuine problem and cannot be waived away by saying “less decimal points and min-value”.

Regarding the crowd-sourcing the rent, this is another unknown. As I described in the document, the problem here is free riding. The smaller holder won’t contribute, because they will hope that the larger holders would. And larger holders might find it expensive, unless they hold supermajority of tokens.

Non-Fungible tokens and similar assets also need special treatment - though they are taken care of in the document by the cross-contract storage. Therefore, I disagree about the over-engineering - it solves lots of problems with one new primitive. I would say - make it as simple as possible, but not simpler.

ADDING MORE FROM THE SAME THREAD

That is great! If someone is prepared to work this out - it would be great. At the moment my position is that these scenarios only work in limited circumstances, and the EVM architecture is lacking primitives to write efficient contract under the rent conditions. I alone cannot explore all the scenarios one can think of, so I invite other people to contribute by making alternative proposals.


#24

Discussion-derailing comment on slide 23:

Token dust griefing attack. Any token holder with access to transfer function can increase storage rent for the contract forever, paying only once for the attack.

This is an over-complication, as things stand.

I’ve described at etheresear.ch earlier this year (and demonstrated using graffiti.lll) how anyone with an ether balance can perform an “allowance griefing attack” to increase storage.

The solution to “allowance griefing” is simple, and is in fact a philosophical correction to ERC-20: namely, make allowances have a validity (time-out) period, with an overriding global period. (This not already being the case is an oversight of ERC-20 standard developers: who, in their right mind, would allow withdrawals forever?..) Outdated allowances become free-for-all gas tokens.


Tokens could require a signed ACK (consent for the receipt of tokens) from recipients.

Nit-picking about nomenclature: it makes sense to call this an ACK when assuming current prevalent use as spam air-drops. Considering that other regular use case, it’d probably be called a REQuest, or similar.

Anyway, this won’t work. The cause for this use of tokens in spam air-drops is marketing. Marketing departments will not cripple themselves into complicated opt-in schemes.

With the introduction of rent, it makes sense then for marketing departments to extend the above-described “time-out” scheme to balances also. An unREQuested, unACKnowledged spam air-drop transfer could be reclaimed by the sender…

I hope you see a pattern here. The proposed REQ/ACK scheme is a mirror image of the existing allowance-transferral scheme. There is no little sense to have both, - unless, as things stand now, one is displayed to the user in-wallet, and the other is not. (Replace “wallet” with “blockchain explorer” if needed, - for what is a wallet, if not a personalised explorer?..)

EDIT: Actually, there is sense to have both - see two comments deeper.

In other words: the underlying problem - that brought us where we are - is as much wallet software design as contract design.


#25

First of all, thanks for reading and commenting! And thank you for pointing out the allowance griefing attack.

Sorry, I did not understand, is this critique about “Alternative point view” (which suggests using signed ACKs for token transfers)? Or is this critique of cross-contract storage?
My main position is that token contracts will have change, and I do not agree with the “Alternative point of view” that one can fix things up on the application level. without changing the storage model. I have not yet explored whether ERC-20 would still be viable under the conditions of state rent.

Regarding the similarities between REQ/ACK and current allowance scheme in ERC-20, I need to think about it more.


#26

Not really; I’m highlighting that requiring signed ACKs for token transfers brings it very close to the existing allowance model.

A comparison (might work better in table format?..):

  • in your (proposed) REQ/ACK transfer scheme:
    • the sender needs to first obtain a REQ/ACK from the receiver, and then
    • perform the transfer themselves;
    • they can’t transfer more than their balance;
    • displaying balances is supported by wallet software;
  • in the (existing) allowance scheme:
    • the sender first sets an allowance, and then
    • waits for a receiver-initiated ACK;
    • can set allowances in excess of their balance, although no more than the balance can actually be claimed by the receivers;
    • displaying allowances - from self or to self - is not supported by any wallet software I know of.

There are subtle differences between the two, and I find both schemes useful.

If anything, so far, this is not (yet) a critique, but a note of agreement and support. :fireworks:


Sorry if that’s the impression my reply gave.

My actual critique is that, as long as there are protocol- and contract-level features (such as allowances or rent) of which wallet-level software is unaware of (and leaves the user unaware of), we will remain in this ditch of trying to solve application-level (both wallet- and game-) problems with protocol-level tools only. Or on the application-level only.

Note that:

  • I’m not referring to the particular balance- or allowance-grieving attacks, which become such with the introduction of rent. Both of these
    • can be solved partially (on the contract-level) with the introduction of time-outs for transfers/allowances, as I’ve mentioned in previous reply; and
    • can probably be solved completely (on the protocol-level) by use of cross-contract storage, as you describe in the slides. (Although, must I say, the images there lack legends, so aren’t very approachable. I’ll go read the comments here and on Reddit before asking for clarifications.)
  • By “game-level problems”, I mean not zombie-cat-warrior toys, but application-level design choices that are mainly game-theoretic; the kind in the saying “if you don’t understand the game, then you’re it”.

My main critique is on the disconnect between actors at various levels in the ecosystem, not your slides. Which why I called my first comment “discussion-derailing”. :slight_smile:

[rant snipped as hindsight]

There are ways to mitigate state growth in the interim, while rent is being developed; but the mitigation would have to come from actors - wallet and game developers - that are indifferent, because they are not being penalised yet. “Oh well”.


#27

I don’t think anyone has discussed cross-contract storage specifically, there was mostly discussions about “why we should not do it this way” :slight_smile: or “why we should not do this at all” :slight_smile:
I am probably not very good with images, because I don’t understand what legends mean in this context :blush:

It was my feeling too. That is why we started this process not by writing EIPs and trying to see if they will get through, but with understanding who will be most affected by the changes on the timeline these changes are likely to be important (next few years, until Ethereum 2.0 or World War III, whichever comes first). And the design of cross-contract storage grew as a solution to grieving and free-riding problems, which I personally think is very hard (or impossible) to solve purely on the application level


#28

I wrote that part while looking at slide 39, before really understanding what slides 39–44 (“Step 3 - Linear cross-contract storage - opcodes”) are about. It does make sense after following the rest of the slides.


EDIT: FTR, I don’t claim to fully understand the cross-contract storage proposal (yet); but it does look good on the surface: it’s less different from the current mode of contracts’ operation than, say, stateless/witness-based. AFAIU, it doesn’t prevent the use of the latter by those who want to; and doesn’t force those who don’t.


#29

Adding myself to the thread here.
I’m a sceptic of linear cross-contract storage (let’s call it LCCS ok?). Here is my main ‘beef’ with it:

The proposal ‘looks and feels’ like a proposal which shifts the problem of state data ownership
over to individual token owners. However, I think it still leaves the actual problem unsolved :

  • Problem: lots of data that the network has to take care of,

  • Implicit solution: delete data that nobody pays for

What the proposal does, is only shifting the ‘blame’ on the individual token owners. So after
we implement that, we can say ‘tokens lost? well, it’s your fault’ instead of saying ‘tokens lost? well, tragedy of the commons’.

And hence, I would much rather try to solve the problem root problem

  • Problem: lots of data that the network has to take care of,

  • Solution: Let the token-owner take care of the data.

And to reach that kind of solution, token contracts would need to be stateless, or at least not O(N) state, at best O(1) but realistically maybe O(log N) or O(sqrt N). So I believe that we should focus on what low-level functionality we can provide to contracts to make stateless-ness easier to implement.

So my ideal route forward would involve these steps

  • Temporal replay protection

  • Dust clearing

  • Tooling for stateless contracts

  • State rent (fjl’s gist)

Regardless if we use LCCS or not, as I see it, all existing tokens will need to be replaced. So if regular state rent is introduced, then

  • Replace token X with an implementation which has
    • Pays for it’s own rent by rewarding rentpayers with tokens
    • Has built-in dust-thresholds, and mechanisms to clean dust
    • Potentially has some form of statelessness

If lccs is implemented, then

  • Replace token X with an implementation which has
    • Storage on user’s accounts
    • Nothing. SFYL when tokens go missing

With the ‘old’ scheme, funds (tokens in cold wallets) will not disappear in a way that they cannot be resurrected. With LCCS, they will disappear forever.


#30

Thanks for comments!

Yes, the introduction of rent itself shift the burden of state maintenance from the protocol to the contracts. And the presented proposal says: “It is not always fair”, so it ALLOWS to shift it further to the token holders, or whoever is beneficiary of that data being stored (if such beneficiary can be identified). It does not force contract developers to do that, but gives them an extra tool, because my belief is that a lot of them will need it

I started to explore stateless contracts on the pages 52-55, and so far identified that the main issues to solve would be “proof contention” (which could be made less bad, but not completely solved, by bucketing the state. complete solution would involve miners updating the proofs, which is a lot of changes in consensus), and a sub-protocol to deliver off-chain data for the new users.

Sorry, it was the case in the earlier version of the proposal, where I forgot to mention that recovery mechanism on the Step 4 will also apply to the LCCS. Have not figured all the details yet, but started on the page 58


#31

Hello, what if normal eth nodes were only required to store merkle root hashes and we outsourced storage to other archival nodes who were paid for the storage by those who wish to conduct transactions? Like part of the TX fee or another tx fee. Those who want to perform TX need to pay the archive nodes for the merkle proofs to submit their tx.

These ‘state provider nodes’ would be responsible for maintaining and storing the Ethereum storage data and would be compensated via micropayments whenever a TX is done.

This way, one tx gas fee is used to pay miners and another tx gas fee is used to pay the archival nodes who are helping the user to submit the Merkle Proofs to the mining nodes. Obviously an eth user needs the merkle proof of, for example , their token balances in order to spend their tokens.

This would mean that the Ethereum state could scale infinitely and we could even separate the data into separate segments such as by perhaps 10,000 block Segments such that there would be multiple Storage Provider nodes for each Segment. It’s easier to do this when we abstract the ‘job’ out to a different class of provider.

The way I imagine it is we have traditional light nodes which mine and hold just merkle roots and process new tx and are compensated, and then we also have these new archival nodes which hold the merkle proofs (all the chain data) for those roots and they are paid whenever someone needs their data.

I mostly suggest this because I think putting the burden on transaction fees is 1000% the way to go here. Forcing smart contracts to pay is NOT right because smart contracts are not people!! Most are non-owned… Take SafeMath for example. How can SafeMath pay it’s bills? Or wEth. Or thousands of other critical contracts who have no central entity to pay their bills! I think we need to just add an additional Tax to transaction fees and make it go towards archival nodes basically. And we do this by having the archival nodes sell the TX submitters the Merkle proofs!!! The data that they need to use to prove to the miners that their new tx is valid :slight_smile:

This would be like a second fee market. ‘Merkle Proofing fees.’


#32

I think we need both on-chain storage (as stated on the page 21), which is limited, and off-chain storage, aka Stateless Contracts - I tried to explore them a bit on pages 52-55. What is not in the document, but will be in the next version - the full solution to the “proof contention” problem requires miners (or validators) to adjust the proofs, and this is perhaps what will start happening in Ethereum 2.0, or in Ethereum 1.0 with a large change to consensus also.
And if we do not introduce state rent, what will motivate people to switch to the outsourced storage? If there is no consequences for keeping data in the state, then people will keep doing until the platform stops working. It is similar to exploitation of biosphere by humankind - we all know we do it, but we don’t stop until everything dies.


#33

Correct me if I’m wrong but in my proposal, essentially all contracts become stateless and the storage outsourced because normal Ethereum nodes would not need to store any state, just a little merkle tree like a light client. We are probably talking about the same thing but with different wording/perspective.

Since every contract is stateless, to do a tx a user must provide a merkle proof (basically the definition of a stateless contract no? ) .

Then the archival/storage nodes could store different parts of the chain ( like shards) and could even be quizzed by the miners to make sure they are storing all the data and not just certain parts. If they fail a quiz, they could be punished and if they pass, they keep getting the fees as rewards.


#34

Yes, I understand you. Though my currentl thinking is that it will probably not be Ethereum anymore, because everything (perhaps apart from EVM) will be different :slight_smile: