Skip to content

Commit

Permalink
State Rent change C draft EIP - Net contract storage size accounting (e…
Browse files Browse the repository at this point in the history
…thereum#2027)

* State Rent change C draft EIP

* Update eip-draft_StateRentCnetContractSizes.md

* Update eip-draft_StateRentCnetContractSizes.md

* Rename eip-draft_StateRentCnetContractSizes.md to eip-2027.md

* Update eip-2027.md

* Update eip-2027.md

* Update eip-2027.md

* Quote "block C" properly

* Update eip-2027.md
  • Loading branch information
AlexeyAkhunov authored and ilanolkies committed Nov 12, 2019
1 parent f90ca33 commit 2ac3e90
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions EIPS/eip-2027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
eip: 2027
title: State Rent C - Net contract size accounting
author: Alexey Akhunov (@AlexeyAkhunov)
discussions-to: https://ethereum-magicians.org/t/eip-2027-net-contract-size-accounting-change-c-from-state-rent-v3-proposal/3275
status: Draft
type: Standards Track
category: Core
created: 2019-05-14
---

<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. This is the suggested template for new EIPs. Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. The title should be 44 characters or less.-->

## Simple Summary
<!--"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP.-->
Ethereum starts counting the number of storage slots filled and emptied in the contracts. Since the number of pre-existing slots is not currently accounted
in the state, effectively, only net change in the number of slots is tracked. In the subsequent change, called *Gross contract size accounting*, the total
number of storage slots starts being tracked.

## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
This is part of the State Rent roadmap. This particular change introduces initial, net accounting of the number of the contract storage slots. Though not very
useful on its own, it makes it possible to introduce gross accounting of the number of storage slots, which is useful for number of things:
1. Gas cost of operations suchs as `SLOAD` and `SSTORE` will need to be increased to compensate for extra bandwidth consumed by the block proofs. Although in
the beginning the cost would be fixed, it will later be automatically calibrated depending on the size of the contract `SLOAD` and `SSTORE` operate on.
2. Snapshot sync protocols, like *fast sync*, *warp sync*, *firehose*, *red queen*, and perhaps others, will benefit from having the correct size of the
contract storage present in the state (and therefore being provable via Merkle proofs).

## Motivation
<!--The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.-->
Ethereum currently does not track the number of contract storage slots at all, and producing such number given the downloaded state cannot be done in
constant *O(1)* time.

## Specification
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
Each contract (account with `codeHash` field not equal to 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, which the hash of the empty code) gets a new uint64 field, called `storagesize`. On and after block `C`, the semantics of the operation `SSTORE` (`location`, `value`) changes as follows:
- If previous value of the [`location`] is 0, and value is not 0, *increment* `storagesize` (semantics of *increment* described below)
- If previous value of the [`location`] is not 0, and value is 0, *decrement* `storagesize` (semantics of *decrement* described below)
- As with other state changes, changes of `storagesize` get reverted when the execution frame reverts, i.e. it needs to use the same techniques as storage values, like journalling (in Geth), and substates (in Parity).
Value of `storagesize` is not observable from contracts at this point.

### Semantics of *increment* `storagesize`
If `storagesize` is not present, `storagesize` = `HUGE_NUMBER` + 1.
If `storagesize` is present, `storagesize` = `storagesize` + 1.

### Semantics of *decrement* `storagesize`
If `storagesize` is not present, `storagesize` = `HUGE_NUMBER` - 1.
If `storagesize` is present, `storagesize` = `storagesize` - 1.

### Note of `HUGE_NUMBER`
There is a constant `HUGE_NUMBER`. It needs to be large enough so that no real metrics (contract storage size, number of accounts, number of contracts, total size of code, total size of storage) will never reach that number, and small enough that it fits in an unsigned 64-bit integer.
Current suggestion is to have `HUGE_NUMBER` = 2^63, which is binary representation is the a single bit in a 64-bit number.

The idea is to make it decidable later whether the storagesize was ever incremented/decremented (presence of the field), and whether it has been converted from net to gross (by value being smaller than `HUGE_NUMBER/2` - because it will not be possible for any contract be larger than 2^62 at the block `C`).

## Rationale
<!--The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->
A mechanism for estimation of contract storage size has been proposed [here](https://medium.com/@akhounov/estimation-approximate-of-the-size-of-contracst-in-ethereum-4642fe92d6fe). But it does have a big drawback of introducing a lot of complexity into the consensus
(in the form of estimation algorithm, which has quite a few edge cases to cater for different sizes of the storage).

## Backwards Compatibility
<!--All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright.-->
This change is not backwards compatible and requires hard fork to be activated. Since the newly introduced field is not observable, this change does not impact any operations of the existing smart contracts.

## Test Cases
<!--Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable.-->
Tests cases will be generated out of a reference implementation.

## Implementation
<!--The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.-->
There will be proof of concept implementation to refine and clarify the specification.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 comments on commit 2ac3e90

Please sign in to comment.