Merge pull request #69 from status-im/add-log-memory-validation
Refactored log opcodes, added validation, fixed a couple of tests
This commit is contained in:
commit
c8be4be5f1
22
VMTests.md
22
VMTests.md
|
@ -487,8 +487,8 @@ OK: 113/145 Fail: 31/145 Skip: 1/145
|
||||||
## vmLogTest
|
## vmLogTest
|
||||||
```diff
|
```diff
|
||||||
+ log0_emptyMem.json OK
|
+ log0_emptyMem.json OK
|
||||||
- log0_logMemStartTooHigh.json Fail
|
+ log0_logMemStartTooHigh.json OK
|
||||||
- log0_logMemsizeTooHigh.json Fail
|
+ log0_logMemsizeTooHigh.json OK
|
||||||
+ log0_logMemsizeZero.json OK
|
+ log0_logMemsizeZero.json OK
|
||||||
+ log0_nonEmptyMem.json OK
|
+ log0_nonEmptyMem.json OK
|
||||||
+ log0_nonEmptyMem_logMemSize1.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_Caller.json OK
|
||||||
+ log1_MaxTopic.json OK
|
+ log1_MaxTopic.json OK
|
||||||
+ log1_emptyMem.json OK
|
+ log1_emptyMem.json OK
|
||||||
- log1_logMemStartTooHigh.json Fail
|
+ log1_logMemStartTooHigh.json OK
|
||||||
- log1_logMemsizeTooHigh.json Fail
|
+ log1_logMemsizeTooHigh.json OK
|
||||||
+ log1_logMemsizeZero.json OK
|
+ log1_logMemsizeZero.json OK
|
||||||
+ log1_nonEmptyMem.json OK
|
+ log1_nonEmptyMem.json OK
|
||||||
+ log1_nonEmptyMem_logMemSize1.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_Caller.json OK
|
||||||
+ log2_MaxTopic.json OK
|
+ log2_MaxTopic.json OK
|
||||||
+ log2_emptyMem.json OK
|
+ log2_emptyMem.json OK
|
||||||
- log2_logMemStartTooHigh.json Fail
|
+ log2_logMemStartTooHigh.json OK
|
||||||
- log2_logMemsizeTooHigh.json Fail
|
+ log2_logMemsizeTooHigh.json OK
|
||||||
+ log2_logMemsizeZero.json OK
|
+ log2_logMemsizeZero.json OK
|
||||||
+ log2_nonEmptyMem.json OK
|
+ log2_nonEmptyMem.json OK
|
||||||
+ log2_nonEmptyMem_logMemSize1.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_MaxTopic.json OK
|
||||||
+ log3_PC.json OK
|
+ log3_PC.json OK
|
||||||
+ log3_emptyMem.json OK
|
+ log3_emptyMem.json OK
|
||||||
- log3_logMemStartTooHigh.json Fail
|
+ log3_logMemStartTooHigh.json OK
|
||||||
- log3_logMemsizeTooHigh.json Fail
|
+ log3_logMemsizeTooHigh.json OK
|
||||||
+ log3_logMemsizeZero.json OK
|
+ log3_logMemsizeZero.json OK
|
||||||
+ log3_nonEmptyMem.json OK
|
+ log3_nonEmptyMem.json OK
|
||||||
+ log3_nonEmptyMem_logMemSize1.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_MaxTopic.json OK
|
||||||
+ log4_PC.json OK
|
+ log4_PC.json OK
|
||||||
+ log4_emptyMem.json OK
|
+ log4_emptyMem.json OK
|
||||||
- log4_logMemStartTooHigh.json Fail
|
+ log4_logMemStartTooHigh.json OK
|
||||||
- log4_logMemsizeTooHigh.json Fail
|
+ log4_logMemsizeTooHigh.json OK
|
||||||
+ log4_logMemsizeZero.json OK
|
+ log4_logMemsizeZero.json OK
|
||||||
+ log4_nonEmptyMem.json OK
|
+ log4_nonEmptyMem.json OK
|
||||||
+ log4_nonEmptyMem_logMemSize1.json OK
|
+ log4_nonEmptyMem_logMemSize1.json OK
|
||||||
+ log4_nonEmptyMem_logMemSize1_logMemStart31.json OK
|
+ log4_nonEmptyMem_logMemSize1_logMemStart31.json OK
|
||||||
+ log_2logs.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
|
## vmPerformance
|
||||||
```diff
|
```diff
|
||||||
ackermann31.json Skip
|
ackermann31.json Skip
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
import
|
import
|
||||||
macros, strformat, stint,
|
macros, strformat, stint,
|
||||||
../../computation, ../../stack, ../../code_stream,
|
../../computation, ../../stack, ../../code_stream,
|
||||||
../../../constants, ../../../vm_types
|
../../../constants, ../../../vm_types, ../../memory,
|
||||||
|
../../../errors, ../../message, ../../interpreter/[gas_meter, opcode_values]
|
||||||
|
|
||||||
proc pop(tree: var NimNode): NimNode =
|
proc pop(tree: var NimNode): NimNode =
|
||||||
## Returns the last value of a NimNode and remove it
|
## Returns the last value of a NimNode and remove it
|
||||||
|
@ -98,60 +99,32 @@ macro genSwap*(): untyped =
|
||||||
func `name`*(computation: var BaseComputation) {.inline.}=
|
func `name`*(computation: var BaseComputation) {.inline.}=
|
||||||
computation.stack.swap(`pos`)
|
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:
|
var topics = newSeqOfCap[UInt256](topicCount)
|
||||||
error(&"Invalid log topic len {topicCount} Must be 0, 1, 2, 3, or 4")
|
for i in 0 ..< topicCount:
|
||||||
return
|
topics.add(c.stack.popInt())
|
||||||
|
c.gasMeter.consumeGas(
|
||||||
let name = ident(&"log{topicCount}")
|
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
|
||||||
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]
|
|
||||||
|
|
||||||
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")
|
reason="Memory expansion, Log topic and data gas cost")
|
||||||
`computation`.memory.extend(`memPos`, `len`)
|
|
||||||
let logData = `computation`.memory.read(`memPos`, `len`)
|
c.memory.extend(memPos, len)
|
||||||
|
let logData = c.memory.read(memPos, len)
|
||||||
addLogEntry(
|
addLogEntry(
|
||||||
`computation`,
|
c,
|
||||||
account = `computation`.msg.storageAddress,
|
account = c.msg.storageAddress,
|
||||||
topics = `topics`,
|
topics = topics,
|
||||||
data = log_data)
|
data = logData)
|
||||||
|
|
||||||
result.body.add(logicCode)
|
template genLog*() =
|
||||||
|
proc log0*(c: var BaseComputation) {.inline.} = logImpl(c, Log0, 0)
|
||||||
macro genLog*(): untyped =
|
proc log1*(c: var BaseComputation) {.inline.} = logImpl(c, Log1, 1)
|
||||||
result = newStmtList()
|
proc log2*(c: var BaseComputation) {.inline.} = logImpl(c, Log2, 2)
|
||||||
for i in 0..4:
|
proc log3*(c: var BaseComputation) {.inline.} = logImpl(c, Log3, 3)
|
||||||
result.add logImpl(i)
|
proc log4*(c: var BaseComputation) {.inline.} = logImpl(c, Log4, 4)
|
||||||
|
|
Loading…
Reference in New Issue