Skip to content

Commit

Permalink
Extend storage status
Browse files Browse the repository at this point in the history
Expand the number of storage statuses to cover all possible EVM
behaviors. These provide enough information to VM to compute not only
gas costs but also refunds. Including legacy SSTORE costs before net
gas metering.
  • Loading branch information
chfast committed Aug 5, 2022
1 parent 4404c62 commit 911af80
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 14 deletions.
74 changes: 61 additions & 13 deletions include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,36 +503,84 @@ typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context,
* notation is used:
* - 0 is zero value,
* - X != 0 (X is any value other than 0),
* - Y != X, Y != 0 (Y is any value other than X and 0),
* - Z != Y (Z is any value other than Y),
* - the "->" means the change from one value to another.
* - Y != 0, Y != X, (Y is any value other than X and 0),
* - Z != 0, Z != X, Z != X (Z is any value other than Y and X and 0),
* - the "o -> c -> v" triple describes the change status in the context of:
* - o: original value (cold value before a transaction started),
* - c: current storage value,
* - v: new storage value to be set.
*
* The order of elements follows EIPs introducing net storage gas costs:
* - EIP-2200: https://eips.ethereum.org/EIPS/eip-2200,
* - EIP-1283: https://eips.ethereum.org/EIPS/eip-1283.
*/
enum evmc_storage_status
{
/**
* The value of a storage item has been left unchanged: 0 -> 0 and X -> X.
* The value of a storage item has been left unchanged has been modified again
* in the transaction context. This is the group of "no-op" cases related to
* minimal gas cost.
* 0|X -> 0 -> 0 (current value unchanged)
* 0|X|Y -> Y -> Y (current value unchanged)
* 0|X -> Y -> Z (modified previously added/modified value)
*/
EVMC_STORAGE_MODIFIED_AGAIN = 0,

/**
* A new storage item is added by changing
* the current clean zero to a nonzero value.
* 0 -> 0 -> Z
*/
EVMC_STORAGE_ADDED = 1,

/**
* A storage item is deleted by changing
* the current clean nonzero to the zero value.
* X -> X -> 0
*/
EVMC_STORAGE_DELETED = 2,

/**
* A storage item is modified by changing
* the current clean nonzero to other nonzero value.
* X -> X -> Z
*/
EVMC_STORAGE_MODIFIED = 3,

/**
* A storage item is added by changing
* the current dirty zero to a nonzero value other than the original value.
* X -> 0 -> Y
*/
EVMC_STORAGE_UNCHANGED = 0,
EVMC_STORAGE_DELETED_ADDED = 4,

/**
* The value of a storage item has been modified: X -> Y.
* A storage item is deleted by changing
* the current dirty nonzero to the zero value and the original value is not zero.
* X -> Y -> 0
*/
EVMC_STORAGE_MODIFIED = 1,
EVMC_STORAGE_MODIFIED_DELETED = 5,

/**
* A storage item has been modified after being modified before: X -> Y -> Z.
* A storage item is added by changing
* the current dirty zero to the original value.
* X -> 0 -> X
*/
EVMC_STORAGE_MODIFIED_AGAIN = 2,
EVMC_STORAGE_DELETED_RESTORED = 6,

/**
* A new storage item has been added: 0 -> X.
* A storage item is deleted by changing
* the current dirty nonzero to the original zero value.
* 0 -> Y -> 0
*/
EVMC_STORAGE_ADDED = 3,
EVMC_STORAGE_ADDED_DELETED = 7,

/**
* A storage item has been deleted: X -> 0.
* A storage item is modified by changing
* the current dirty nonzero to the original nonzero value other than the current value.
* X -> Y -> X
*/
EVMC_STORAGE_DELETED = 4
EVMC_STORAGE_MODIFIED_RESTORED = 8
};


Expand Down
2 changes: 1 addition & 1 deletion include/evmc/mocked_host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class MockedHost : public Host
// WARNING! This is not complete implementation as refund is not handled here.

if (old.value == value)
return EVMC_STORAGE_UNCHANGED;
return EVMC_STORAGE_MODIFIED_AGAIN;

evmc_storage_status status{};
if (!old.dirty)
Expand Down

0 comments on commit 911af80

Please sign in to comment.