EVM: use assign2 whenever possible (#2499)
Before: GST finish in 59 secs. After: GST finish in 52 secs!
This commit is contained in:
parent
8d1e21bbae
commit
cfe14f1825
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -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()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in New Issue