EVM: use assign2 whenever possible (#2499)

Before: GST finish in 59 secs.
After: GST finish in 52 secs!
This commit is contained in:
andri lim 2024-07-17 20:48:50 +07:00 committed by GitHub
parent 8d1e21bbae
commit cfe14f1825
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 74 deletions

View File

@ -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:

View File

@ -30,6 +30,7 @@ import
chronicles,
eth/common,
eth/common/eth_types,
stew/assign2,
stint
when not defined(evmc_enabled):
@ -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:
@ -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()
# ---------------------
@ -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()
# ---------------------
@ -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()
# ---------------------
@ -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()
# ------------------------------------------------------------------------------

View File

@ -31,6 +31,7 @@ import
chronicles,
eth/common,
eth/common/eth_types,
stew/assign2,
stint
when not defined(evmc_enabled):
@ -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()
@ -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()
# ---------------------
@ -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()
# ------------------------------------------------------------------------------

View File

@ -17,6 +17,7 @@ import
chronicles,
nimcrypto/[ripemd, sha2, utils],
bncurve/[fields, groups],
stew/assign2,
../common/evmforks,
../core/eip4844,
./modexp,
@ -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.} =
@ -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 =
@ -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 =
@ -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 =
@ -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,
@ -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 =
@ -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 =
@ -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 =
@ -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 =
@ -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 =