Memory and storage opcodes: TODO stateDB handler for the storage to work
This commit is contained in:
parent
0ec03afced
commit
59bef848aa
|
@ -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,
|
||||
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],
|
||||
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:
|
||||
# arithmetic
|
||||
|
@ -67,11 +67,16 @@ var opcodes = initOpcodes:
|
|||
1..16 Op.DupXX: GAS_VERY_LOW dupXX
|
||||
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.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
|
||||
|
|
Loading…
Reference in New Issue