Memory and storage opcodes: TODO stateDB handler for the storage to work
This commit is contained in:
parent
0ec03afced
commit
59bef848aa
|
@ -111,7 +111,7 @@ let
|
||||||
GAS_COINBASE* = 20.i256
|
GAS_COINBASE* = 20.i256
|
||||||
GAS_SLOAD_COST* = 20.i256
|
GAS_SLOAD_COST* = 20.i256
|
||||||
GAS_SELF_DESTRUCT_COST* = 5_000.i256
|
GAS_SELF_DESTRUCT_COST* = 5_000.i256
|
||||||
|
|
||||||
REFUNDS_CLEAR* = 15_000.i256
|
REFUNDS_CLEAR* = 15_000.i256
|
||||||
|
|
||||||
GAS_SELF_DESTRUCT* = 0.i256
|
GAS_SELF_DESTRUCT* = 0.i256
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import
|
|
||||||
../constants, ../computation, .. / vm / [stack, memory], ../utils/padding
|
|
||||||
|
|
||||||
|
|
||||||
proc mstoreX(computation: var BaseComputation, x: int) =
|
|
||||||
let start = computation.stack.popInt()
|
|
||||||
let value = computation.stack.popBinary()
|
|
||||||
|
|
||||||
let paddedValue = pad_left(value, x, cstring"\x00")
|
|
||||||
let normalizedValue = cstring(($paddedValue)[^x .. ^1])
|
|
||||||
|
|
||||||
computation.extendMemory(start, x.int256)
|
|
||||||
computation.memory.write(start, 32.int256, normalizedValue)
|
|
||||||
|
|
||||||
template mstore*(computation: var BaseComputation) =
|
|
||||||
mstoreX(32)
|
|
||||||
|
|
||||||
template mstore8*(computation: var BaseComputation) =
|
|
||||||
mstoreX(1)
|
|
||||||
|
|
||||||
proc mload*(computation: var BaseComputation) =
|
|
||||||
let start = computation.stack.popInt()
|
|
||||||
|
|
||||||
computation.extendMemory(start, 32.int256)
|
|
||||||
|
|
||||||
let value = computation.memory.read(start, 32.int256)
|
|
||||||
computation.stack.push(value)
|
|
||||||
|
|
||||||
proc msize*(computation: var BaseComputation) =
|
|
||||||
computation.stack.push(computation.memory.len)
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import
|
||||||
|
../constants, ../computation, .. / vm / [stack, memory], .. / utils / [padding, bytes]
|
||||||
|
|
||||||
|
|
||||||
|
{.this: computation.}
|
||||||
|
{.experimental.}
|
||||||
|
|
||||||
|
using
|
||||||
|
computation: var BaseComputation
|
||||||
|
|
||||||
|
proc mstoreX(computation; x: int) =
|
||||||
|
let start = stack.popInt()
|
||||||
|
let value = stack.popBinary()
|
||||||
|
|
||||||
|
let paddedValue = padLeft(value, x, cstring"\x00")
|
||||||
|
let normalizedValue = cstring(($paddedValue)[^x .. ^1])
|
||||||
|
|
||||||
|
extendMemory(start, x.int256)
|
||||||
|
memory.write(start, 32.int256, normalizedValue)
|
||||||
|
|
||||||
|
proc mstore*(computation) {.inline.} =
|
||||||
|
mstoreX(32)
|
||||||
|
|
||||||
|
proc mstore8*(computation) {.inline.} =
|
||||||
|
mstoreX(1)
|
||||||
|
|
||||||
|
proc mload*(computation) =
|
||||||
|
let start = stack.popInt()
|
||||||
|
|
||||||
|
extendMemory(start, 32.int256)
|
||||||
|
|
||||||
|
let value = memory.read(start, 32.int256).toCstring
|
||||||
|
stack.push(value)
|
||||||
|
|
||||||
|
proc msize*(computation) =
|
||||||
|
stack.push(memory.len)
|
|
@ -0,0 +1,66 @@
|
||||||
|
import
|
||||||
|
../constants, ../errors, ../computation, .. / db / state_db, .. / vm / [stack, gas_meter, message]
|
||||||
|
|
||||||
|
{.this: computation.}
|
||||||
|
{.experimental.}
|
||||||
|
|
||||||
|
using
|
||||||
|
computation: var BaseComputation
|
||||||
|
|
||||||
|
proc sstore*(computation) =
|
||||||
|
let (slot, value) = stack.popInt(2)
|
||||||
|
|
||||||
|
# TODO: stateDB
|
||||||
|
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||||
|
# current_value = state_db.get_storage(
|
||||||
|
# address=computation.msg.storage_address,
|
||||||
|
# slot=slot,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# let isCurrentlyEmpty = not bool(current_value)
|
||||||
|
# let isGoingToBeEmpty = not bool(value)
|
||||||
|
|
||||||
|
# if is_currently_empty:
|
||||||
|
# gas_refund = 0
|
||||||
|
# elif is_going_to_be_empty:
|
||||||
|
# gas_refund = constants.REFUND_SCLEAR
|
||||||
|
# else:
|
||||||
|
# gas_refund = 0
|
||||||
|
|
||||||
|
# if is_currently_empty and is_going_to_be_empty:
|
||||||
|
# gas_cost = constants.GAS_SRESET
|
||||||
|
# elif is_currently_empty:
|
||||||
|
# gas_cost = constants.GAS_SSET
|
||||||
|
# elif is_going_to_be_empty:
|
||||||
|
# gas_cost = constants.GAS_SRESET
|
||||||
|
# else:
|
||||||
|
# gas_cost = constants.GAS_SRESET
|
||||||
|
|
||||||
|
# computation.gas_meter.consume_gas(gas_cost, reason="SSTORE: {0}[{1}] -> {2} ({3})".format(
|
||||||
|
# encode_hex(computation.msg.storage_address),
|
||||||
|
# slot,
|
||||||
|
# value,
|
||||||
|
# current_value,
|
||||||
|
# ))
|
||||||
|
|
||||||
|
# if gas_refund:
|
||||||
|
# computation.gas_meter.refund_gas(gas_refund)
|
||||||
|
|
||||||
|
# with computation.vm_state.state_db() as state_db:
|
||||||
|
# state_db.set_storage(
|
||||||
|
# address=computation.msg.storage_address,
|
||||||
|
# slot=slot,
|
||||||
|
# value=value,
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
|
proc sload*(computation) =
|
||||||
|
let slot = stack.popInt()
|
||||||
|
|
||||||
|
# TODO: with
|
||||||
|
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||||
|
# value = state_db.get_storage(
|
||||||
|
# address=computation.msg.storage_address,
|
||||||
|
# slot=slot,
|
||||||
|
# )
|
||||||
|
# computation.stack.push(value)
|
|
@ -2,7 +2,7 @@ import
|
||||||
strformat, strutils, tables, macros,
|
strformat, strutils, tables, macros,
|
||||||
constants, bigints, errors, logging, vm_state,
|
constants, bigints, errors, logging, vm_state,
|
||||||
vm / [gas_meter, stack, code_stream, memory, message, value, gas_costs], db / chain, computation, opcode, opcode_values, utils / [header, address],
|
vm / [gas_meter, stack, code_stream, memory, message, value, gas_costs], db / chain, computation, opcode, opcode_values, utils / [header, address],
|
||||||
logic / [arithmetic, comparison, sha3, context, block_ops, stack_ops, duplication, swap]
|
logic / [arithmetic, comparison, sha3, context, block_ops, stack_ops, duplication, swap, memory_ops, storage]
|
||||||
|
|
||||||
var opcodes = initOpcodes:
|
var opcodes = initOpcodes:
|
||||||
# arithmetic
|
# arithmetic
|
||||||
|
@ -67,11 +67,16 @@ var opcodes = initOpcodes:
|
||||||
1..16 Op.DupXX: GAS_VERY_LOW dupXX
|
1..16 Op.DupXX: GAS_VERY_LOW dupXX
|
||||||
1..16 Op.SwapXX: GAS_VERY_LOW swapXX
|
1..16 Op.SwapXX: GAS_VERY_LOW swapXX
|
||||||
|
|
||||||
# Op.MLoad: GAS_VERY_LOW mload
|
|
||||||
|
# memory
|
||||||
|
Op.MLoad: GAS_VERY_LOW mload
|
||||||
# Op.MStore: GAS_VERY_LOW mstore
|
# Op.MStore: GAS_VERY_LOW mstore
|
||||||
# Op.MStore8: GAS_VERY_LOW mstore8
|
# Op.MStore8: GAS_VERY_LOW mstore8
|
||||||
# Op.SLoad: GAS_SLOAD_COST sload
|
|
||||||
# Op.SStore: 0.i256 sstore
|
|
||||||
|
# storage
|
||||||
|
Op.SLoad: GAS_SLOAD_COST sload
|
||||||
|
Op.SStore: GAS_ZERO sstore
|
||||||
|
|
||||||
|
|
||||||
# Op.Jump: GAS_MID jump
|
# Op.Jump: GAS_MID jump
|
||||||
|
|
Loading…
Reference in New Issue