Skip to content

Commit

Permalink
Add cold/warm cases for sload and sstore
Browse files Browse the repository at this point in the history
  • Loading branch information
gianbelinche committed Apr 11, 2024
1 parent afa4660 commit 0ed32f5
Showing 1 changed file with 74 additions and 6 deletions.
80 changes: 74 additions & 6 deletions system-contracts/contracts/EvmInterpreter.yul
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,44 @@ object "EVMInterpreter" {
mstore(DEBUG_SLOT_OFFSET(), 0x4A15830341869CAA1E99840C97043A1EA15D2444DA366EFFF5C43B4BEF299681)
}

function isSlotWarm(key) -> isWarm {
// TODO: Unhardcode this selector 0x482d2e74
mstore8(0, 0x48)
mstore8(1, 0x2d)
mstore8(2, 0x2e)
mstore8(3, 0x74)
mstore(4, key)

let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 36, 0, 32)

if iszero(success) {
// This error should never happen
revert(0, 0)
}

isWarm := mload(0)
}

function warmSlot(key,currentValue) -> isWarm, originalValue {
// TODO: Unhardcode this selector 0xbdf78160
mstore8(0, 0xbd)
mstore8(1, 0xf7)
mstore8(2, 0x81)
mstore8(3, 0x60)
mstore(4, key)
mstore(36,currentValue)

let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 64)

if iszero(success) {
// This error should never happen
revert(0, 0)
}

isWarm := mload(0)
originalValue := mload(32)
}

////////////////////////////////////////////////////////////////
// FALLBACK
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -338,25 +376,55 @@ object "EVMInterpreter" {
sp := pushStackItem(sp, mulmod(a, b, N))
}
case 0x54 { // OP_SLOAD
let key,value
let key,value,isWarm

key, sp := popStackItem(sp)

isWarm := isSlotWarm(key)
switch isWarm
case 0 { evmGasLeft := chargeGas(evmGasLeft,2100) }
default { evmGasLeft := chargeGas(evmGasLeft,100) }

value := sload(key)

sp := pushStackItem(sp,value)
// TODO: Handle cold/warm slots and updates, etc for gas costs.
evmGasLeft := chargeGas(evmGasLeft,100)
}
case 0x55 { // OP_SSTORE
let key, value
let key, value,gasSpent

key, sp := popStackItem(sp)
value, sp := popStackItem(sp)

{
// Here it is okay to read before we charge since we known anyway that
// the context has enough funds to compensate at least for the read.
// Im not sure if we need this before: require(gasLeft > GAS_CALL_STIPEND);
let currentValue := sload(key)
let wasWarm,originalValue := warmSlot(key,currentValue)
gasSpent := 100
if and(not(eq(value,currentValue)),eq(originalValue,currentValue)) {
switch originalValue
case 0 { gasSpent := 20000}
default { gasSpent := 2900}
}
if iszero(wasWarm) {
gasSpent := add(gasSpent,2100)
}
}

evmGasLeft := chargeGas(evmGasLeft, gasSpent) //gasSpent
sstore(key, value)
// TODO: Handle cold/warm slots and updates, etc for gas costs.
evmGasLeft := chargeGas(evmGasLeft, 100)
}
case 0x59 { // OP_MSIZE
evmGasLeft := chargeGas(evmGasLeft,2)

//sp := pushStackItem(sp,)

}
case 0x5A { // OP_GAS (should conflict with yul-environment-1 branch, retain changes in that branch, ditch this one)
evmGasLeft := chargeGas(evmGasLeft, 2)

sp := pushStackItem(sp, evmGasLeft)
}
case 0x5F { // OP_PUSH0
let value := 0
Expand Down

0 comments on commit 0ed32f5

Please sign in to comment.