Skip to content

Commit

Permalink
EVM: use assign2 whenever possible (#2499)
Browse files Browse the repository at this point in the history
Before: GST finish in 59 secs.
After: GST finish in 52 secs!
  • Loading branch information
jangko committed Jul 17, 2024
1 parent 8d1e21b commit cfe14f1
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 74 deletions.
8 changes: 4 additions & 4 deletions nimbus/evm/computation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ proc dispose*(c: Computation) =
proc rollback*(c: Computation) =
c.vmState.stateDB.rollback(c.savePoint)

func setError*(c: Computation, msg: string, burnsGas = false) =
c.error = Error(evmcStatus: EVMC_FAILURE, info: msg, burnsGas: burnsGas)
func setError*(c: Computation, msg: sink string, burnsGas = false) =
c.error = Error(evmcStatus: EVMC_FAILURE, info: move(msg), burnsGas: burnsGas)

func setError*(c: Computation, code: evmc_status_code, burnsGas = false) =
c.error = Error(evmcStatus: code, info: $code, burnsGas: burnsGas)

func setError*(
c: Computation, code: evmc_status_code, msg: string, burnsGas = false) =
c.error = Error(evmcStatus: code, info: msg, burnsGas: burnsGas)
c: Computation, code: evmc_status_code, msg: sink string, burnsGas = false) =
c.error = Error(evmcStatus: code, info: move(msg), burnsGas: burnsGas)

func evmcStatus*(c: Computation): evmc_status_code =
if c.isSuccess:
Expand Down
87 changes: 46 additions & 41 deletions nimbus/evm/interpreter/op_handlers/oph_call.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import
chronicles,
eth/common,
eth/common/eth_types,
stew/assign2,
stint

when not defined(evmc_enabled):
Expand Down Expand Up @@ -158,7 +159,7 @@ proc staticCallParams(c: Computation): EvmResult[LocalParams] =
when evmc_enabled:
template execSubCall(c: Computation; msg: ref nimbus_message; p: LocalParams) =
c.chainTo(msg):
c.returnData = @(makeOpenArray(c.res.output_data, c.res.output_size.int))
assign(c.returnData, makeOpenArray(c.res.output_data, c.res.output_size.int))

let actualOutputSize = min(p.memOutLen, c.returnData.len)
if actualOutputSize > 0:
Expand Down Expand Up @@ -263,19 +264,20 @@ proc callOp(k: var VmCtx): EvmResultVoid =
)
c.execSubCall(msg, p)
else:
var childMsg = Message(
kind: EVMC_CALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
flags: p.flags)
assign(childMsg.data, cpt.memory.read(p.memInPos, p.memInLen))
cpt.execSubCall(
memPos = p.memOutPos,
memLen = p.memOutLen,
childMsg = Message(
kind: EVMC_CALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
data: @(cpt.memory.read(p.memInPos, p.memInLen)),
flags: p.flags))
childMsg = childMsg)
ok()

# ---------------------
Expand Down Expand Up @@ -335,19 +337,20 @@ proc callCodeOp(k: var VmCtx): EvmResultVoid =
)
c.execSubCall(msg, p)
else:
var childMsg = Message(
kind: EVMC_CALLCODE,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
flags: p.flags)
assign(childMsg.data, cpt.memory.read(p.memInPos, p.memInLen))
cpt.execSubCall(
memPos = p.memOutPos,
memLen = p.memOutLen,
childMsg = Message(
kind: EVMC_CALLCODE,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
data: @(cpt.memory.read(p.memInPos, p.memInLen)),
flags: p.flags))
childMsg = childMsg)
ok()

# ---------------------
Expand Down Expand Up @@ -402,19 +405,20 @@ proc delegateCallOp(k: var VmCtx): EvmResultVoid =
)
c.execSubCall(msg, p)
else:
var childMsg = Message(
kind: EVMC_DELEGATECALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
flags: p.flags)
assign(childMsg.data, cpt.memory.read(p.memInPos, p.memInLen))
cpt.execSubCall(
memPos = p.memOutPos,
memLen = p.memOutLen,
childMsg = Message(
kind: EVMC_DELEGATECALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
data: @(cpt.memory.read(p.memInPos, p.memInLen)),
flags: p.flags))
childMsg = childMsg)
ok()

# ---------------------
Expand Down Expand Up @@ -470,19 +474,20 @@ proc staticCallOp(k: var VmCtx): EvmResultVoid =
)
c.execSubCall(msg, p)
else:
var childMsg = Message(
kind: EVMC_CALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
flags: p.flags)
assign(childMsg.data, cpt.memory.read(p.memInPos, p.memInLen))
cpt.execSubCall(
memPos = p.memOutPos,
memLen = p.memOutLen,
childMsg = Message(
kind: EVMC_CALL,
depth: cpt.msg.depth + 1,
gas: childGasLimit,
sender: p.sender,
contractAddress: p.contractAddress,
codeAddress: p.codeAddress,
value: p.value,
data: @(cpt.memory.read(p.memInPos, p.memInLen)),
flags: p.flags))
childMsg = childMsg)
ok()

# ------------------------------------------------------------------------------
Expand Down
36 changes: 18 additions & 18 deletions nimbus/evm/interpreter/op_handlers/oph_create.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import
chronicles,
eth/common,
eth/common/eth_types,
stew/assign2,
stint

when not defined(evmc_enabled):
Expand All @@ -54,7 +55,7 @@ when evmc_enabled:
? c.stack.top(c.res.create_address)
elif c.res.status_code == EVMC_REVERT:
# From create, only use `outputData` if child returned with `REVERT`.
c.returnData = @(makeOpenArray(c.res.output_data, c.res.output_size.int))
assign(c.returnData, makeOpenArray(c.res.output_data, c.res.output_size.int))
if not c.res.release.isNil:
c.res.release(c.res)
ok()
Expand Down Expand Up @@ -152,14 +153,14 @@ proc createOp(k: var VmCtx): EvmResultVoid =
)
c.execSubCreate(msg)
else:
cpt.execSubCreate(
childMsg = Message(
kind: EVMC_CREATE,
depth: cpt.msg.depth + 1,
gas: createMsgGas,
sender: cpt.msg.contractAddress,
value: endowment,
data: @(cpt.memory.read(memPos, memLen))))
var childMsg = Message(
kind: EVMC_CREATE,
depth: cpt.msg.depth + 1,
gas: createMsgGas,
sender: cpt.msg.contractAddress,
value: endowment)
assign(childMsg.data, cpt.memory.read(memPos, memLen))
cpt.execSubCreate(childMsg)
ok()

# ---------------------
Expand Down Expand Up @@ -234,15 +235,14 @@ proc create2Op(k: var VmCtx): EvmResultVoid =
)
c.execSubCreate(msg)
else:
cpt.execSubCreate(
salt = salt,
childMsg = Message(
kind: EVMC_CREATE2,
depth: cpt.msg.depth + 1,
gas: createMsgGas,
sender: cpt.msg.contractAddress,
value: endowment,
data: @(cpt.memory.read(memPos, memLen))))
var childMsg = Message(
kind: EVMC_CREATE2,
depth: cpt.msg.depth + 1,
gas: createMsgGas,
sender: cpt.msg.contractAddress,
value: endowment)
assign(childMsg.data, cpt.memory.read(memPos, memLen))
cpt.execSubCreate(salt = salt, childMsg = childMsg)
ok()

# ------------------------------------------------------------------------------
Expand Down
23 changes: 12 additions & 11 deletions nimbus/evm/precompiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import
chronicles,
nimcrypto/[ripemd, sha2, utils],
bncurve/[fields, groups],
stew/assign2,
../common/evmforks,
../core/eip4844,
./modexp,
Expand Down Expand Up @@ -104,7 +105,7 @@ func getSignature(c: Computation): EvmResult[SigRes] =
var res = SigRes(sig: sig)

# extract message hash, only need to copy when there is a valid signature
res.msgHash[0..31] = data[0..31]
assign(res.msgHash, data.toOpenArray(0, 31))
ok(res)

func simpleDecode(dst: var FQ2, src: openArray[byte]): bool {.noinit.} =
Expand Down Expand Up @@ -160,7 +161,7 @@ func ecRecover(c: Computation): EvmResultVoid =
return err(prcErr(PrcInvalidSig))

c.output.setLen(32)
c.output[12..31] = pubkey.toCanonicalAddress()
assign(c.output.toOpenArray(12, 31), pubkey.toCanonicalAddress())
ok()

func sha256(c: Computation): EvmResultVoid =
Expand All @@ -169,7 +170,7 @@ func sha256(c: Computation): EvmResultVoid =
gasFee = GasSHA256 + wordCount.GasInt * GasSHA256Word

? c.gasMeter.consumeGas(gasFee, reason="SHA256 Precompile")
c.output = @(sha2.sha256.digest(c.msg.data).data)
assign(c.output, sha2.sha256.digest(c.msg.data).data)
ok()

func ripemd160(c: Computation): EvmResultVoid =
Expand All @@ -179,7 +180,7 @@ func ripemd160(c: Computation): EvmResultVoid =

? c.gasMeter.consumeGas(gasFee, reason="RIPEMD160 Precompile")
c.output.setLen(32)
c.output[12..31] = @(ripemd.ripemd160.digest(c.msg.data).data)
assign(c.output.toOpenArray(12, 31), ripemd.ripemd160.digest(c.msg.data).data)
ok()

func identity(c: Computation): EvmResultVoid =
Expand All @@ -188,7 +189,7 @@ func identity(c: Computation): EvmResultVoid =
gasFee = GasIdentity + wordCount.GasInt * GasIdentityWord

? c.gasMeter.consumeGas(gasFee, reason="Identity Precompile")
c.output = c.msg.data
assign(c.output, c.msg.data)
ok()

func modExpFee(c: Computation,
Expand Down Expand Up @@ -288,10 +289,10 @@ func modExp(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
# maximum output len is the same as modLen
# if it less than modLen, it will be zero padded at left
if output.len >= modLen:
c.output = @(output[^modLen..^1])
assign(c.output, output.toOpenArray(output.len-modLen, output.len-1))
else:
c.output = newSeq[byte](modLen)
c.output[^output.len..^1] = output[0..^1]
assign(c.output.toOpenArray(c.output.len-output.len, c.output.len-1), output)
ok()

func bn256ecAdd(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
Expand All @@ -311,7 +312,7 @@ func bn256ecAdd(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
# we can discard here because we supply proper buffer
discard apo.get().toBytes(output)

c.output = @output
assign(c.output, output)
ok()

func bn256ecMul(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
Expand All @@ -332,7 +333,7 @@ func bn256ecMul(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
# we can discard here because we supply buffer of proper size
discard apo.get().toBytes(output)

c.output = @output
assign(c.output, output)
ok()

func bn256ecPairing(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid =
Expand Down Expand Up @@ -370,7 +371,7 @@ func bn256ecPairing(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid
# we can discard here because we supply buffer of proper size
discard BNU256.one().toBytes(output)

c.output = @output
assign(c.output, output)
ok()

func blake2bf(c: Computation): EvmResultVoid =
Expand All @@ -385,7 +386,7 @@ func blake2bf(c: Computation): EvmResultVoid =
if not blake2b_F(input, output):
return err(prcErr(PrcInvalidParam))
else:
c.output = @output
assign(c.output, output)
ok()

func blsG1Add*(c: Computation): EvmResultVoid =
Expand Down

0 comments on commit cfe14f1

Please sign in to comment.