Skip to content

Commit 674e65f

Browse files
authored
Move EVM code initialization outside of newComputation (#2926)
* Move EVM code initialization outside of newComputation * Tidying up call_common.setupHost
1 parent 7b88bb3 commit 674e65f

File tree

13 files changed

+157
-214
lines changed

13 files changed

+157
-214
lines changed

nimbus/evm/computation.nim

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import
1414
std/sequtils,
1515
".."/[db/ledger, constants],
16-
"."/[code_stream, memory, message, stack, state],
16+
"."/[code_stream, memory, stack, state],
1717
"."/[types],
1818
./interpreter/[gas_meter, gas_costs, op_codes],
1919
./evm_errors,
@@ -46,17 +46,6 @@ when defined(evmc_enabled):
4646
const
4747
evmc_enabled* = defined(evmc_enabled)
4848

49-
# ------------------------------------------------------------------------------
50-
# Helpers
51-
# ------------------------------------------------------------------------------
52-
53-
proc generateContractAddress(c: Computation, salt: ContractSalt): Address =
54-
if c.msg.kind == EVMC_CREATE:
55-
let creationNonce = c.vmState.readOnlyStateDB().getNonce(c.msg.sender)
56-
result = generateAddress(c.msg.sender, creationNonce)
57-
else:
58-
result = generateSafeAddress(c.msg.sender, salt, c.msg.data)
59-
6049
# ------------------------------------------------------------------------------
6150
# Public functions
6251
# ------------------------------------------------------------------------------
@@ -259,42 +248,17 @@ template resolveCode*(c: Computation, address: Address): CodeBytesRef =
259248
else:
260249
c.vmState.readOnlyStateDB.resolveCode(address)
261250

262-
proc newComputation*(vmState: BaseVMState, sysCall: bool, message: Message,
263-
isPrecompile, keepStack: bool, salt: ContractSalt = ZERO_CONTRACTSALT): Computation =
264-
new result
265-
result.vmState = vmState
266-
result.msg = message
267-
result.gasMeter.init(message.gas)
268-
result.sysCall = sysCall
269-
result.keepStack = keepStack
270-
271-
if not isPrecompile:
272-
result.memory = EvmMemory.init()
273-
result.stack = EvmStack.init()
274-
275-
if result.msg.isCreate():
276-
result.msg.contractAddress = result.generateContractAddress(salt)
277-
result.code = CodeStream.init(message.data)
278-
message.data = @[]
279-
else:
280-
if vmState.fork >= FkPrague:
281-
result.code = CodeStream.init(
282-
vmState.readOnlyStateDB.resolveCode(message.codeAddress))
283-
else:
284-
result.code = CodeStream.init(
285-
vmState.readOnlyStateDB.getCode(message.codeAddress))
286-
287-
288-
func newComputation*(vmState: BaseVMState, sysCall: bool,
289-
message: Message, code: CodeBytesRef, isPrecompile, keepStack: bool, ): Computation =
251+
func newComputation*(vmState: BaseVMState,
252+
keepStack: bool,
253+
message: Message,
254+
code = CodeBytesRef(nil)): Computation =
290255
new result
291256
result.vmState = vmState
292257
result.msg = message
293258
result.gasMeter.init(message.gas)
294-
result.sysCall = sysCall
295259
result.keepStack = keepStack
296260

297-
if not isPrecompile:
261+
if not code.isNil:
298262
result.code = CodeStream.init(code)
299263
result.memory = EvmMemory.init()
300264
result.stack = EvmStack.init()

nimbus/evm/evmc_helpers.nim

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ func toEvmc*(h: Hash32): evmc_bytes32 {.inline.} =
2424
doAssert sizeof(h) == sizeof(evmc_bytes32)
2525
evmc_bytes32(bytes: h.data)
2626

27-
func toEvmc*(h: ContractSalt): evmc_bytes32 {.inline.} =
27+
func toEvmc*(h: Bytes32): evmc_bytes32 {.inline.} =
2828
doAssert sizeof(h) == sizeof(evmc_bytes32)
29-
cast[evmc_bytes32](h)
29+
evmc_bytes32(bytes: h.data)
3030

3131
func toEvmc*(n: UInt256): evmc_uint256be {.inline.} =
3232
when evmc_native:
@@ -35,9 +35,9 @@ func toEvmc*(n: UInt256): evmc_uint256be {.inline.} =
3535
cast[evmc_uint256be](n.toBytesBE)
3636

3737
func fromEvmc*(T: type, n: evmc_bytes32): T {.inline.} =
38-
when T is ContractSalt:
38+
when T is Bytes32:
3939
doAssert sizeof(n) == sizeof(T)
40-
cast[T](n)
40+
T(n.bytes)
4141
elif T is Hash32:
4242
Hash32(n.bytes)
4343
elif T is UInt256:
@@ -63,6 +63,6 @@ when isMainModule:
6363
var h = EMPTY_SHA3
6464
var eh = toEvmc(h)
6565
assert(h == fromEvmc(Hash32, eh))
66-
var s = cast[ContractSalt](EMPTY_ROOT_HASH)
66+
var s = Bytes32(EMPTY_ROOT_HASH.data)
6767
var es = toEvmc(s)
68-
assert(s == fromEvmc(ContractSalt, es))
68+
assert(s == fromEvmc(Bytes32, es))

nimbus/evm/interpreter/op_handlers/oph_call.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import
2121
../../../core/eip7702,
2222
../../computation,
2323
../../memory,
24-
../../precompiles,
2524
../../stack,
2625
../../types,
2726
../gas_costs,
@@ -39,6 +38,7 @@ import
3938
when not defined(evmc_enabled):
4039
import
4140
../../state,
41+
../../message,
4242
../../../db/ledger
4343
else:
4444
import
@@ -203,9 +203,9 @@ else:
203203
# need to provide explicit <c> and <child> for capturing in chainTo proc()
204204
# <memPos> and <memLen> are provided by value and need not be captured
205205
var
206-
precompile = getPrecompile(c.fork, childMsg.codeAddress)
206+
code = getCallCode(c.vmState, childMsg.codeAddress)
207207
child = newComputation(
208-
c.vmState, false, childMsg, isPrecompile = precompile.isSome(), keepStack = false)
208+
c.vmState, keepStack = false, childMsg, code)
209209

210210
c.chainTo(child):
211211
if not child.shouldBurnGas:

nimbus/evm/interpreter/op_handlers/oph_create.nim

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ import
3131
chronicles,
3232
eth/common,
3333
eth/common/eth_types,
34-
stew/assign2,
3534
stint
3635

3736
when not defined(evmc_enabled):
3837
import
3938
../../state,
39+
../../message,
4040
../../../db/ledger
4141
else:
4242
import
43+
stew/assign2,
4344
stew/saturation_arith
4445

4546
# ------------------------------------------------------------------------------
@@ -62,12 +63,12 @@ when evmc_enabled:
6263

6364
else:
6465
proc execSubCreate(c: Computation; childMsg: Message;
65-
salt: ContractSalt = ZERO_CONTRACTSALT) {.raises: [].} =
66+
code: CodeBytesRef) {.raises: [].} =
6667
## Create new VM -- helper for `Create`-like operations
6768

6869
# need to provide explicit <c> and <child> for capturing in chainTo proc()
6970
var
70-
child = newComputation(c.vmState, false, childMsg, false, false, salt)
71+
child = newComputation(c.vmState, keepStack = false, childMsg, code)
7172

7273
c.chainTo(child):
7374
if not child.shouldBurnGas:
@@ -154,14 +155,19 @@ proc createOp(cpt: VmCpt): EvmResultVoid =
154155
)
155156
c.execSubCreate(msg)
156157
else:
157-
var childMsg = Message(
158-
kind: EVMC_CREATE,
159-
depth: cpt.msg.depth + 1,
160-
gas: createMsgGas,
161-
sender: cpt.msg.contractAddress,
162-
value: endowment)
163-
assign(childMsg.data, cpt.memory.read(memPos, memLen))
164-
cpt.execSubCreate(childMsg)
158+
var
159+
childMsg = Message(
160+
kind: EVMC_CREATE,
161+
depth: cpt.msg.depth + 1,
162+
gas: createMsgGas,
163+
sender: cpt.msg.contractAddress,
164+
contractAddress: generateContractAddress(
165+
cpt.vmState,
166+
EVMC_CREATE,
167+
cpt.msg.contractAddress),
168+
value: endowment)
169+
code = CodeBytesRef.init(cpt.memory.read(memPos, memLen))
170+
cpt.execSubCreate(childMsg, code)
165171
ok()
166172

167173
# ---------------------
@@ -176,7 +182,7 @@ proc create2Op(cpt: VmCpt): EvmResultVoid =
176182
memPos = cpt.stack.lsPeekSafeInt(^2)
177183
memLen = cpt.stack.lsPeekSafeInt(^3)
178184
salt256 = cpt.stack.lsPeekInt(^4)
179-
salt = ContractSalt(bytes: salt256.toBytesBE)
185+
salt = Bytes32(salt256.toBytesBE)
180186

181187
cpt.stack.lsShrink(3)
182188
cpt.stack.lsTop(0)
@@ -237,14 +243,21 @@ proc create2Op(cpt: VmCpt): EvmResultVoid =
237243
)
238244
c.execSubCreate(msg)
239245
else:
240-
var childMsg = Message(
241-
kind: EVMC_CREATE2,
242-
depth: cpt.msg.depth + 1,
243-
gas: createMsgGas,
244-
sender: cpt.msg.contractAddress,
245-
value: endowment)
246-
assign(childMsg.data, cpt.memory.read(memPos, memLen))
247-
cpt.execSubCreate(salt = salt, childMsg = childMsg)
246+
var
247+
code = CodeBytesRef.init(cpt.memory.read(memPos, memLen))
248+
childMsg = Message(
249+
kind: EVMC_CREATE2,
250+
depth: cpt.msg.depth + 1,
251+
gas: createMsgGas,
252+
sender: cpt.msg.contractAddress,
253+
contractAddress: generateContractAddress(
254+
cpt.vmState,
255+
EVMC_CREATE2,
256+
cpt.msg.contractAddress,
257+
salt,
258+
code),
259+
value: endowment)
260+
cpt.execSubCreate(childMsg, code)
248261
ok()
249262

250263
# ------------------------------------------------------------------------------

nimbus/evm/interpreter_dispatch.nim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,13 @@ else:
264264
c.dispose()
265265
c = c.parent
266266

267+
proc postExecComputation*(c: Computation) =
268+
if c.isSuccess:
269+
if c.fork < FkLondon:
270+
# EIP-3529: Reduction in refunds
271+
c.refundSelfDestruct()
272+
c.vmState.status = c.isSuccess
273+
267274
# ------------------------------------------------------------------------------
268275
# End
269276
# ------------------------------------------------------------------------------

nimbus/evm/message.nim

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Nimbus
2-
# Copyright (c) 2018 Status Research & Development GmbH
2+
# Copyright (c) 2018-2024 Status Research & Development GmbH
33
# Licensed under either of
44
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
55
# http://www.apache.org/licenses/LICENSE-2.0)
@@ -8,7 +8,35 @@
88
# at your option. This file may not be copied, modified, or distributed except
99
# according to those terms.
1010

11-
import ./types
11+
import
12+
./types,
13+
./state,
14+
./code_bytes,
15+
./precompiles,
16+
../common/evmforks,
17+
../utils/utils,
18+
../db/ledger
1219

1320
proc isCreate*(message: Message): bool =
1421
message.kind in {EVMC_CREATE, EVMC_CREATE2}
22+
23+
proc generateContractAddress*(vmState: BaseVMState,
24+
kind: CallKind,
25+
sender: Address,
26+
salt = ZERO_CONTRACTSALT,
27+
code = CodeBytesRef(nil)): Address =
28+
if kind == EVMC_CREATE:
29+
let creationNonce = vmState.readOnlyStateDB().getNonce(sender)
30+
generateAddress(sender, creationNonce)
31+
else:
32+
generateSafeAddress(sender, salt, code.bytes)
33+
34+
proc getCallCode*(vmState: BaseVMState, codeAddress: Address): CodeBytesRef =
35+
let isPrecompile = getPrecompile(vmState.fork, codeAddress).isSome()
36+
if isPrecompile:
37+
return CodeBytesRef(nil)
38+
39+
if vmState.fork >= FkPrague:
40+
vmState.readOnlyStateDB.resolveCode(codeAddress)
41+
else:
42+
vmState.readOnlyStateDB.getCode(codeAddress)

nimbus/evm/state_transactions.nim

Lines changed: 0 additions & 34 deletions
This file was deleted.

nimbus/evm/types.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ type
9494
else:
9595
parent*, child*: Computation
9696
continuation*: proc(): EvmResultVoid {.gcsafe, raises: [].}
97-
sysCall*: bool
9897
keepStack*: bool
9998
finalStack*: seq[UInt256]
10099

0 commit comments

Comments
 (0)