Memory and storage opcodes: TODO stateDB handler for the storage to work

This commit is contained in:
Alexander Ivanov 2018-01-30 15:07:37 +02:00
parent 0ec03afced
commit 59bef848aa
5 changed files with 112 additions and 35 deletions

View File

@ -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

View File

@ -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)

36
src/logic/memory_ops.nim Normal file
View File

@ -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)

66
src/logic/storage.nim Normal file
View File

@ -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)

View File

@ -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