Appearance
Abstract
Two new opcodes that atomically mutate smart contract storage are proposed: SCREDIT, which increments a storage slot by a specified value, and SDEBIT, which decrements a storage slot by a specified value. Overflow and underflow errors are enforced, reverting when an unsigned 256-bit integer would overflow or underflow.
Motivation
There has been a large amount of energy around parallel EVMs across multiple chains, however there is a lack of parallel primitives within the EVM to support any model other than optimistic concurrency control (OCC). By adding concurrent increment and decrement operations more advanced parallel environments can be introduced in Layer 2 networks.
This also provides the opportunity to serve the principal use case of increment and decrement: token balances. We can introduce failures on overflow and underflow conditions and provide an operation that is also useful outside of parallel use cases.
Specification
Two operations to atomically increment and decrement a storage will be introduced at 0xTBD
. Each operation takes two stack arguments and has no immediate arguments. Gas schedule will be the same as SSTORE.
Mnemonic | Op | Input | Output |
---|---|---|---|
SCREDIT | 0xTBD | 2 | 0 |
SDEBIT | 0xTBD+1 | 2 | 0 |
SCREDIT
SCREDIT: slot, value
Description
Adds value
to the value stored in contract storage slot.
If an overflow would occur the operation halts exceptionally.
Gas Charging
Gas charging is identical to SSTORE. including interactions with the warm storage slot list. Any future modifications to the SSTORE gas charges will also apply to SCREDIT.
Execution
Not valid python, not suitable for EELS yet
slot = evm_stack.pop()
value = evm_stack.pop()
storage_value = read_contract_storage(slot)
storage_value = storage_value + value
if storage_value >= 2**256 :
raise Exception("scredit overflow")
write_contract_storage(storage_value)
SDEBIT
SDEBIT: slot, value
Description
Subtracts value
to the value stored in contract storage slot.
If an underflow would occur the operation halts exceptionally.
Gas Charging
Gas charging is identical to SSTORE, including interactions with the warm storage slot list. Any future modifications to the SSTORE gas charges will also apply to SDEBIT.
Execution
Not valid python, not suitable for EELS yet
slot = evm_stack.pop()
value = evm_stack.pop()
storage_value = read_contract_storage(slot)
storage_value = storage_value - value
if storage_value < 0 :
raise Exception("sdebit underflow")
write_contract_storage(storage_value)
Rationale
The primary consideration when choosing between alternatives is that the primary intended audiences is token contracts and other asset-tracking contracts combined with a desire to ship the minimum necessary changes to enable that use case. General concurrency controls is not a goal of this EIP.
Enforcing Overflow Semantics
When allowing for out-of-order execution there needs to be mechanism to handle any possible order of execution. OCC handles this by validating pre- and post-conditions, and re-evaluating the transactions if those invariants did not hold. This technique breaks down around writing to balances and counters.
Increment/decrement with rollover checking allows for simple handling of balances and counters while allowing for functional read support ensuring that sufficient balance or count exists without depending on the exact values. This allows for evaluation models where the only post-condition checked is to validate that the storage slots could handle all possible re-ordering of transactions.
Gas Schedule
The decision to cost the operations at the exact same value as SSTORE is partly for ease of implementation and partly as an incentive to compilers and developers.
These semantics could be implemented in the EVM today, but it would also include a SLOAD, DUP, LT, JUMPI and REVERT instructions. The EVM, however, can do these operations much more efficiently than via opcodes. First, each SSTORE always incurs a slot load in order to apply EIP-2200 gas calculation rules. This load is essential if there is no paired SLOAD. Math libraries for 256-bit numbers can all easily be made sensitive to overflow and underflow, if they are not already present. Conditional logic handling is also much faster in the operation logic as most of the overhead would be operation parsing and stack management when interpreted.
The net impact of the most relevant operations to the most expensive evaluation (an ADD and LT operation, above the cost of a plain SSTORE) would be 4 gas, or 0.2% of the current cost of a SSTORE. Finally, database access costs dominate the real cost of the operation. A 0.2% overhead may disappear in I/O stalls.
Keeping the cost the same makes implementations of gas charging vert simple.
Storage Slots Only
This most important use case for this EIP asset balances and not general concurrency controls. Hence, only enabling credit and debit operations on storage slots (which persist across transactions). Parallel execution within a transaction and more generic tools like locks and semaphores have very limited utility within this scope. The lack of in-transaction parallel execution also precludes the use of such primitives against transient storage (as defined in EIP-1153).
Opcode Instead of System Contract
One alternative, particularly viable for Layer 2 chains, would be to implement SCREDIT and SDEBIT as system contracts. The primary objection to system contracts for other operations is the gas cost overhead of constructing a call. Because a SSTORE is always greater than the cost of a call it would be possible to build in a discount. However, there is no such accommodation that can be made for the code size needed to invoke such a call.
Backwards Compatibility
These opcodes are not simple replacements for SLOAD-(ADD|SUB)-SSTORE sequence because there is an overflow/underflow check
There is no EVM functionality removed by this proposal.
Test Cases
Test for overflow and non-overflow for the following values and values before and after:
1, 2^8, 2^16, 2^32, 2^64, 2^128 2^255, 2^256-1.
Reference Implementation
/# TBD
Security Considerations
The use of revert to handle over/underflow represents a new halt condition that auditors will need to consider when examining reentrancy concerns.
Copyright
Copyright and related rights waived via CC0.