Refactored log opcodes, added validation, fixed a couple of tests

This commit is contained in:
Yuriy Glukhov 2018-07-13 18:54:33 +03:00
parent 9c88710ed6
commit 46a8b5dc49
2 changed files with 38 additions and 65 deletions

View File

@ -487,8 +487,8 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
## vmLogTest
```diff
+ log0_emptyMem.json OK
- log0_logMemStartTooHigh.json Fail
- log0_logMemsizeTooHigh.json Fail
+ log0_logMemStartTooHigh.json OK
+ log0_logMemsizeTooHigh.json OK
+ log0_logMemsizeZero.json OK
+ log0_nonEmptyMem.json OK
+ log0_nonEmptyMem_logMemSize1.json OK
@ -496,8 +496,8 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
+ log1_Caller.json OK
+ log1_MaxTopic.json OK
+ log1_emptyMem.json OK
- log1_logMemStartTooHigh.json Fail
- log1_logMemsizeTooHigh.json Fail
+ log1_logMemStartTooHigh.json OK
+ log1_logMemsizeTooHigh.json OK
+ log1_logMemsizeZero.json OK
+ log1_nonEmptyMem.json OK
+ log1_nonEmptyMem_logMemSize1.json OK
@ -505,8 +505,8 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
+ log2_Caller.json OK
+ log2_MaxTopic.json OK
+ log2_emptyMem.json OK
- log2_logMemStartTooHigh.json Fail
- log2_logMemsizeTooHigh.json Fail
+ log2_logMemStartTooHigh.json OK
+ log2_logMemsizeTooHigh.json OK
+ log2_logMemsizeZero.json OK
+ log2_nonEmptyMem.json OK
+ log2_nonEmptyMem_logMemSize1.json OK
@ -515,8 +515,8 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
+ log3_MaxTopic.json OK
+ log3_PC.json OK
+ log3_emptyMem.json OK
- log3_logMemStartTooHigh.json Fail
- log3_logMemsizeTooHigh.json Fail
+ log3_logMemStartTooHigh.json OK
+ log3_logMemsizeTooHigh.json OK
+ log3_logMemsizeZero.json OK
+ log3_nonEmptyMem.json OK
+ log3_nonEmptyMem_logMemSize1.json OK
@ -525,15 +525,15 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
+ log4_MaxTopic.json OK
+ log4_PC.json OK
+ log4_emptyMem.json OK
- log4_logMemStartTooHigh.json Fail
- log4_logMemsizeTooHigh.json Fail
+ log4_logMemStartTooHigh.json OK
+ log4_logMemsizeTooHigh.json OK
+ log4_logMemsizeZero.json OK
+ log4_nonEmptyMem.json OK
+ log4_nonEmptyMem_logMemSize1.json OK
+ log4_nonEmptyMem_logMemSize1_logMemStart31.json OK
+ log_2logs.json OK
```
OK: 36/46 Fail: 10/46 Skip: 0/46
OK: 46/46 Fail: 0/46 Skip: 0/46
## vmPerformance
```diff
ackermann31.json Skip

View File

@ -11,7 +11,8 @@
import
macros, strformat, stint,
../../computation, ../../stack, ../../code_stream,
../../../constants, ../../../vm_types
../../../constants, ../../../vm_types, ../../memory,
../../../errors, ../../message, ../../interpreter/[gas_meter, opcode_values]
proc pop(tree: var NimNode): NimNode =
## Returns the last value of a NimNode and remove it
@ -98,60 +99,32 @@ macro genSwap*(): untyped =
func `name`*(computation: var BaseComputation) {.inline.}=
computation.stack.swap(`pos`)
proc logImpl(topicCount: int): NimNode =
proc logImpl(c: var BaseComputation, opcode: Op, topicCount: int) =
assert(topicCount in 0 .. 4)
let (memStartPosition, size) = c.stack.popInt(2)
let (memPos, len) = (memStartPosition.toInt, size.toInt)
# TODO: use toopenArray to avoid some string allocations
if memPos < 0 or len < 0:
raise newException(OutOfBoundsRead, "Out of bounds memory access")
if topicCount < 0 or topicCount > 4:
error(&"Invalid log topic len {topicCount} Must be 0, 1, 2, 3, or 4")
return
var topics = newSeqOfCap[UInt256](topicCount)
for i in 0 ..< topicCount:
topics.add(c.stack.popInt())
c.gasMeter.consumeGas(
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
reason="Memory expansion, Log topic and data gas cost")
let name = ident(&"log{topicCount}")
let computation = ident("computation")
let topics = ident("topics")
let topicsTuple = ident("topicsTuple")
let len = ident("len")
let memPos = ident("memPos")
result = quote:
proc `name`*(`computation`: var BaseComputation) =
let (memStartPosition, size) = `computation`.stack.popInt(2)
let (`memPos`, `len`) = (memStartPosition.toInt, size.toInt)
var `topics`: seq[UInt256]
c.memory.extend(memPos, len)
let logData = c.memory.read(memPos, len)
addLogEntry(
c,
account = c.msg.storageAddress,
topics = topics,
data = logData)
var topicCode: NimNode
if topicCount == 0:
topicCode = quote:
`topics` = @[]
elif topicCount > 1:
topicCode = quote:
let `topicsTuple` = `computation`.stack.popInt(`topicCount`)
topicCode = nnkStmtList.newTree(topicCode)
for z in 0 ..< topicCount:
let topicPush = quote:
`topics`.add(`topicsTuple`[`z`])
topicCode.add(topicPush)
else:
topicCode = quote:
`topics` = @[`computation`.stack.popInt()]
result.body.add(topicCode)
let OpName = ident(&"Log{topicCount}")
let logicCode = quote do:
`computation`.gasMeter.consumeGas(
`computation`.gasCosts[`OpName`].m_handler(`computation`.memory.len, `memPos`, `len`),
reason="Memory expansion, Log topic and data gas cost")
`computation`.memory.extend(`memPos`, `len`)
let logData = `computation`.memory.read(`memPos`, `len`)
addLogEntry(
`computation`,
account = `computation`.msg.storageAddress,
topics = `topics`,
data = log_data)
result.body.add(logicCode)
macro genLog*(): untyped =
result = newStmtList()
for i in 0..4:
result.add logImpl(i)
template genLog*() =
proc log0*(c: var BaseComputation) {.inline.} = logImpl(c, Log0, 0)
proc log1*(c: var BaseComputation) {.inline.} = logImpl(c, Log1, 1)
proc log2*(c: var BaseComputation) {.inline.} = logImpl(c, Log2, 2)
proc log3*(c: var BaseComputation) {.inline.} = logImpl(c, Log3, 3)
proc log4*(c: var BaseComputation) {.inline.} = logImpl(c, Log4, 4)