Prepare the remaining opcodes, implement context opcodes
This commit is contained in:
parent
5ad14f59b2
commit
0fa5c5fd94
|
@ -107,6 +107,10 @@ let
|
|||
GAS_JUMP_DEST* = 1.i256
|
||||
GAS_SSET* = 20_000.i256
|
||||
GAS_SRESET* = 5000.i256
|
||||
GAS_EXT_CODE_COST* = 700.i256
|
||||
GAS_COINBASE* = 20.i256
|
||||
GAS_SLOAD_COST* = 20.i256
|
||||
GAS_SELF_DESTRUCT_COST* = 5_000.i256
|
||||
|
||||
REFUNDS_CLEAR* = 15_000.i256
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import
|
||||
../constants, ../utils_numeric, ../computation, ../vm_state, ../account, ../db/state_db, ../validation,
|
||||
.. / vm / [stack, message], .. / utils / [address, padding, bytes]
|
||||
strformat,
|
||||
../constants, ../errors, ../utils_numeric, ../computation, ../vm_state, ../account, ../db/state_db, ../validation,
|
||||
.. / vm / [stack, message, gas_meter, memory, code_stream], .. / utils / [address, padding, bytes], bigints
|
||||
|
||||
proc balance*(computation: var BaseComputation) =
|
||||
let address = forceBytesToAddress(computation.stack.popBinary)
|
||||
|
@ -35,124 +36,84 @@ proc callDataSize*(computation: var BaseComputation) =
|
|||
let size = computation.msg.data.len
|
||||
computation.stack.push(size)
|
||||
|
||||
# def calldatacopy(computation):
|
||||
# (
|
||||
# mem_start_position,
|
||||
# calldata_start_position,
|
||||
# size,
|
||||
# ) = computation.stack.pop(num_items=3, type_hint=constants.UINT256)
|
||||
proc callDataCopy*(computation: var BaseComputation) =
|
||||
let (memStartPosition,
|
||||
calldataStartPosition,
|
||||
size) = computation.stack.popInt(3)
|
||||
computation.extendMemory(memStartPosition, size)
|
||||
|
||||
# computation.extend_memory(mem_start_position, size)
|
||||
|
||||
# word_count = ceil32(size) // 32
|
||||
# copy_gas_cost = word_count * constants.GAS_COPY
|
||||
|
||||
# computation.gas_meter.consume_gas(copy_gas_cost, reason="CALLDATACOPY fee")
|
||||
|
||||
# value = computation.msg.data[calldata_start_position: calldata_start_position + size]
|
||||
# padded_value = pad_right(value, size, b'\x00')
|
||||
|
||||
# computation.memory.write(mem_start_position, size, padded_value)
|
||||
let wordCount = ceil32(size) div 32
|
||||
let copyGasCost = wordCount * constants.GAS_COPY
|
||||
computation.gasMeter.consumeGas(copyGasCost, reason="CALLDATACOPY fee")
|
||||
let value = computation.msg.data[calldataStartPosition.getInt ..< (calldataStartPosition + size).getInt].toCString
|
||||
let paddedValue = padRight(value, size.getInt, cstring"\x00")
|
||||
computation.memory.write(memStartPosition, size, paddedValue)
|
||||
|
||||
|
||||
# def codesize(computation):
|
||||
# size = len(computation.code)
|
||||
# computation.stack.push(size)
|
||||
proc codesize*(computation: var BaseComputation) =
|
||||
let size = computation.code.len.i256
|
||||
computation.stack.push(size)
|
||||
|
||||
|
||||
# def codecopy(computation):
|
||||
# (
|
||||
# mem_start_position,
|
||||
# code_start_position,
|
||||
# size,
|
||||
# ) = computation.stack.pop(num_items=3, type_hint=constants.UINT256)
|
||||
proc codecopy*(computation: var BaseComputation) =
|
||||
let (memStartPosition,
|
||||
codeStartPosition,
|
||||
size) = computation.stack.popInt(3)
|
||||
computation.extendMemory(memStartPosition, size)
|
||||
let wordCount = ceil32(size) div 32
|
||||
let copyGasCost = constants.GAS_COPY * wordCount
|
||||
|
||||
# computation.extend_memory(mem_start_position, size)
|
||||
|
||||
# word_count = ceil32(size) // 32
|
||||
# copy_gas_cost = constants.GAS_COPY * word_count
|
||||
|
||||
# computation.gas_meter.consume_gas(
|
||||
# copy_gas_cost,
|
||||
# reason="CODECOPY: word gas cost",
|
||||
# )
|
||||
|
||||
# with computation.code.seek(code_start_position):
|
||||
# code_bytes = computation.code.read(size)
|
||||
|
||||
# padded_code_bytes = pad_right(code_bytes, size, b'\x00')
|
||||
|
||||
# computation.memory.write(mem_start_position, size, padded_code_bytes)
|
||||
computation.gasMeter.consumeGas(copyGasCost, reason="CODECOPY: word gas cost")
|
||||
# TODO
|
||||
# with computation.code.seek(code_start_position):
|
||||
# code_bytes = computation.code.read(size)
|
||||
# padded_code_bytes = pad_right(code_bytes, size, b'\x00')
|
||||
# computation.memory.write(mem_start_position, size, padded_code_bytes)
|
||||
|
||||
|
||||
# def gasprice(computation):
|
||||
# computation.stack.push(computation.msg.gas_price)
|
||||
proc gasprice*(computation: var BaseComputation) =
|
||||
computation.stack.push(computation.msg.gasPrice)
|
||||
|
||||
|
||||
# def extcodesize(computation):
|
||||
# account = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES))
|
||||
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||
# code_size = len(state_db.get_code(account))
|
||||
proc extCodeSize*(computation: var BaseComputation) =
|
||||
let account = forceBytesToAddress(computation.stack.popBinary)
|
||||
# TODO
|
||||
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||
# code_size = len(state_db.get_code(account))
|
||||
|
||||
# computation.stack.push(code_size)
|
||||
# computation.stack.push(code_size)
|
||||
|
||||
proc extCodeCopy*(computation: var BaseComputation) =
|
||||
let account = forceBytesToAddress(computation.stack.popBinary)
|
||||
let (memStartPosition, codeStartPosition, size) = computation.stack.popInt(3)
|
||||
computation.extendMemory(memStartPosition, size)
|
||||
let wordCount = ceil32(size) div 32
|
||||
let copyGasCost = constants.GAS_COPY * wordCount
|
||||
|
||||
# def extcodecopy(computation):
|
||||
# account = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES))
|
||||
# (
|
||||
# mem_start_position,
|
||||
# code_start_position,
|
||||
# size,
|
||||
# ) = computation.stack.pop(num_items=3, type_hint=constants.UINT256)
|
||||
computation.gasMeter.consumeGas(copyGasCost, reason="EXTCODECOPY: word gas cost")
|
||||
|
||||
# computation.extend_memory(mem_start_position, size)
|
||||
# TODO:
|
||||
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||
# code = state_db.get_code(account)
|
||||
# code_bytes = code[code_start_position:code_start_position + size]
|
||||
# padded_code_bytes = pad_right(code_bytes, size, b'\x00')
|
||||
# computation.memory.write(mem_start_position, size, padded_code_bytes)
|
||||
|
||||
# word_count = ceil32(size) // 32
|
||||
# copy_gas_cost = constants.GAS_COPY * word_count
|
||||
proc returnDataSize*(computation: var BaseComputation) =
|
||||
let size = computation.returnData.len
|
||||
computation.stack.push(size)
|
||||
|
||||
# computation.gas_meter.consume_gas(
|
||||
# copy_gas_cost,
|
||||
# reason='EXTCODECOPY: word gas cost',
|
||||
# )
|
||||
proc returnDataCopy*(computation: var BaseComputation) =
|
||||
let (memStartPosition, returnDataStartPosition, size) = computation.stack.popInt(3)
|
||||
if returnDataStartPosition + size > computation.returnData.len:
|
||||
raise newException(OutOfBoundsRead,
|
||||
"Return data length is not sufficient to satisfy request. Asked \n" &
|
||||
&"for data from index {returnDataStartPosition} to {returnDataStartPosition + size}. Return data is {computation.returnData.len} in \n" &
|
||||
"length")
|
||||
|
||||
# with computation.vm_state.state_db(read_only=True) as state_db:
|
||||
# code = state_db.get_code(account)
|
||||
# code_bytes = code[code_start_position:code_start_position + size]
|
||||
# padded_code_bytes = pad_right(code_bytes, size, b'\x00')
|
||||
|
||||
# computation.memory.write(mem_start_position, size, padded_code_bytes)
|
||||
|
||||
|
||||
# def returndatasize(computation):
|
||||
# size = len(computation.return_data)
|
||||
# computation.stack.push(size)
|
||||
|
||||
|
||||
# def returndatacopy(computation):
|
||||
# (
|
||||
# mem_start_position,
|
||||
# returndata_start_position,
|
||||
# size,
|
||||
# ) = computation.stack.pop(num_items=3, type_hint=constants.UINT256)
|
||||
|
||||
# if returndata_start_position + size > len(computation.return_data):
|
||||
# raise OutOfBoundsRead(
|
||||
# "Return data length is not sufficient to satisfy request. Asked "
|
||||
# "for data from index {0} to {1}. Return data is {2} bytes in "
|
||||
# "length.".format(
|
||||
# returndata_start_position,
|
||||
# returndata_start_position + size,
|
||||
# len(computation.return_data),
|
||||
# )
|
||||
# )
|
||||
|
||||
# computation.extend_memory(mem_start_position, size)
|
||||
|
||||
# word_count = ceil32(size) // 32
|
||||
# copy_gas_cost = word_count * constants.GAS_COPY
|
||||
|
||||
# computation.gas_meter.consume_gas(copy_gas_cost, reason="RETURNDATACOPY fee")
|
||||
|
||||
# value = computation.return_data[returndata_start_position: returndata_start_position + size]
|
||||
|
||||
# computation.memory.write(mem_start_position, size, value)
|
||||
computation.extendMemory(memStartPosition, size)
|
||||
let wordCount = ceil32(size) div 32
|
||||
let copyGasCost = wordCount * constants.GAS_COPY
|
||||
computation.gasMeter.consumeGas(copyGasCost, reason="RETURNDATACOPY fee")
|
||||
let value = cstring(($computation.returnData)[returnDataStartPosition.getInt ..< (returnDataStartPosition + size).getInt])
|
||||
computation.memory.write(memStartPosition, size, value)
|
||||
|
|
|
@ -45,6 +45,49 @@ var opcodes = initOpcodes:
|
|||
Op.CallValue: GAS_BASE callValue
|
||||
Op.CallDataLoad: GAS_VERY_LOW callDataLoad
|
||||
Op.CallDataSize: GAS_BASE callDataSize
|
||||
Op.CallDataCopy: GAS_BASE callDataCopy
|
||||
Op.CodeSize: GAS_BASE codesize
|
||||
Op.CodeCopy: GAS_BASE codecopy
|
||||
Op.ExtCodeSize: GAS_EXT_CODE_COST extCodeSize
|
||||
Op.ExtCodeCopy: GAS_EXT_CODE_COST extCodeCopy
|
||||
|
||||
|
||||
# Op.Blockhash: GAS_BASE blockhash
|
||||
# Op.Coinbase: GAS_COINBASE coinbase
|
||||
# Op.Timestamp: GAS_BASE timestamp
|
||||
# Op.Number: GAS_BASE number
|
||||
# Op.Difficulty: GAS_BASE difficulty
|
||||
# Op.GasLimit: GAS_BASE gasLimitOp
|
||||
# Op.Pop: GAS_BASE popOp
|
||||
# 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
|
||||
|
||||
|
||||
# Op.Jump: GAS_MID jump
|
||||
# Op.JumpI: GAS_MID jumpI
|
||||
# Op.PC: GAS_HIGH pc
|
||||
# Op.MSize: GAS_BASE msize
|
||||
# Op.Gas: GAS_BASE gasOp
|
||||
# Op.JumpDest: GAS_JUMP_DEST jumpDest
|
||||
# Op.Push: GAS_VERY_LOW push
|
||||
# Op.Dup: GAS_VERY_LOW dup
|
||||
# Op.Swap: GAS_VERY_LOW swap
|
||||
# Op.Log0: GAS_LOG log0
|
||||
# Op.Log1: 2 * GAS_LOG log1
|
||||
# Op.Log2: 3 * GAS_LOG log2
|
||||
# Op.Log3: 4 * GAS_LOG log3
|
||||
# Op.Log4: 5 * GAS_LOG log4
|
||||
|
||||
# Op.Create: GAS_CREATE create
|
||||
# Op.Call: 0.i256 callOp
|
||||
# Op.CallCode: 0.i256 callCodeOp
|
||||
# Op.Return: 0.i256 returnOp
|
||||
# Op.DelegateCall: 0.i256 delegateCall
|
||||
# Op.Invalid: 0.i256 invalidOp
|
||||
# Op.SelfDestruct: GAS_SELF_DESTRUCT_COST selfDestruct
|
||||
|
||||
var mem = newMemory(pow(1024.int256, 2))
|
||||
|
||||
|
@ -90,7 +133,7 @@ var c = BaseComputation(
|
|||
macro runOpcodes*(computation: untyped, program: untyped): untyped =
|
||||
# runOpcodes(c):
|
||||
# stack: @[Value..]
|
||||
#
|
||||
#
|
||||
# Op
|
||||
# Op
|
||||
#
|
||||
|
@ -125,5 +168,5 @@ runOpcodes(c):
|
|||
Op.Div
|
||||
Op.Sub
|
||||
Op.Mul
|
||||
Op.Mul
|
||||
Op.Mul
|
||||
|
||||
|
|
Loading…
Reference in New Issue