diff --git a/src/constants.nim b/src/constants.nim index 7b50cadd5..433b6dba2 100644 --- a/src/constants.nim +++ b/src/constants.nim @@ -111,7 +111,7 @@ let GAS_COINBASE* = 20.i256 GAS_SLOAD_COST* = 20.i256 GAS_SELF_DESTRUCT_COST* = 5_000.i256 - + GAS_IN_HANDLER* = 0.i256 # to be calculated in handler REFUNDS_CLEAR* = 15_000.i256 GAS_SELF_DESTRUCT* = 0.i256 diff --git a/src/logic/logging_ops.nim b/src/logic/logging_ops.nim new file mode 100644 index 000000000..b36b24528 --- /dev/null +++ b/src/logic/logging_ops.nim @@ -0,0 +1,64 @@ +import + strformat, macros, + ../constants, ../errors, ../computation, .. / vm / [stack, memory, gas_meter, message], .. / utils / bytes, bigints + +{.this: computation.} +{.experimental.} + +using + computation: var BaseComputation + +macro logXX(topicCount: static[int]): untyped = + if topicCount < 0 or topicCount > 4: + error(&"Invalid log topic size {topicCount} Must be 0, 1, 2, 3, or 4") + return + + let name = ident(&"log{topicCount}") + let computation = ident("computation") + let topics = ident("topics") + let topicsTuple = ident("topicsTuple") + let size = ident("size") + let memStartPosition = ident("memStartPosition") + result = quote: + proc `name`*(`computation`: var BaseComputation) = + let (`memStartPosition`, `size`) = `computation`.stack.popInt(2) + var `topics`: seq[Int256] + + 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 logicCode = quote: + let dataGasCost = constants.GAS_LOG_DATA * `size` + let topicGasCost = constants.GAS_LOG_TOPIC * `topicCount`.i256 + let totalGasCost = dataGasCost + topicGasCost + `computation`.gasMeter.consumeGas(totalGasCost, reason="Log topic and data gas cost") + `computation`.extendMemory(`memStartPosition`, `size`) + let logData = `computation`.memory.read(`memStartPosition`, `size`).toCString + `computation`.addLogEntry( + account=`computation`.msg.storageAddress, + topics=`topics`, + data=log_data) + + result.body.add(logicCode) + # echo result.repr + +logXX(0) +logXX(1) +logXX(2) +logXX(3) +logXX(4) diff --git a/src/runner.nim b/src/runner.nim index 1b1cda394..a903b86b1 100644 --- a/src/runner.nim +++ b/src/runner.nim @@ -88,11 +88,9 @@ var opcodes = initOpcodes: Op.Stop: GAS_ZERO stop - # 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 + + # logging + 0..4 Op.LogXX: GAS_IN_HANDLER logXX # Op.Create: GAS_CREATE create # Op.Call: 0.i256 callOp