--- 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 --- ## Simple Summary 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 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 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 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 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 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 Tests cases will be generated out of a reference implementation. ## Implementation 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/).