mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-13 05:44:40 +00:00
Fix EVM tracer: capture exception properly
Also fix EVM to support new tracer
This commit is contained in:
parent
465d694834
commit
80aec9ccd9
@ -396,9 +396,6 @@ proc traceOpCodeStarted*(c: Computation, op: Op): int {.gcsafe, raises: [].} =
|
|||||||
c.gasMeter.gasRemaining,
|
c.gasMeter.gasRemaining,
|
||||||
c.msg.depth + 1)
|
c.msg.depth + 1)
|
||||||
|
|
||||||
proc traceCallFamilyGas*(c: Computation, op: Op, gas: GasInt) {.gcsafe, raises: [].} =
|
|
||||||
c.vmState.callFamilyGas(c, op, gas, c.msg.depth + 1)
|
|
||||||
|
|
||||||
proc traceOpCodeEnded*(c: Computation, op: Op, opIndex: int) {.gcsafe, raises: [].} =
|
proc traceOpCodeEnded*(c: Computation, op: Op, opIndex: int) {.gcsafe, raises: [].} =
|
||||||
c.vmState.captureOpEnd(
|
c.vmState.captureOpEnd(
|
||||||
c,
|
c,
|
||||||
@ -424,6 +421,15 @@ proc traceError*(c: Computation) {.gcsafe, raises: [].} =
|
|||||||
proc prepareTracer*(c: Computation) =
|
proc prepareTracer*(c: Computation) =
|
||||||
c.vmState.capturePrepare(c, c.msg.depth)
|
c.vmState.capturePrepare(c, c.msg.depth)
|
||||||
|
|
||||||
|
proc opcodeGastCost*(c: Computation, op: Op, gasCost: GasInt, reason: string) {.gcsafe, raises: [OutOfGas, ValueError].} =
|
||||||
|
c.vmState.captureGasCost(
|
||||||
|
c,
|
||||||
|
op,
|
||||||
|
gasCost,
|
||||||
|
c.gasMeter.gasRemaining,
|
||||||
|
c.msg.depth + 1)
|
||||||
|
c.gasMeter.consumeGas(gasCost, reason)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -94,7 +94,8 @@ type
|
|||||||
GckFixed,
|
GckFixed,
|
||||||
GckDynamic,
|
GckDynamic,
|
||||||
GckMemExpansion,
|
GckMemExpansion,
|
||||||
GckComplex
|
GckComplex,
|
||||||
|
GckLater
|
||||||
|
|
||||||
GasResult = tuple[gasCost, gasRefund: GasInt]
|
GasResult = tuple[gasCost, gasRefund: GasInt]
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ type
|
|||||||
case kind*: GasCostKind
|
case kind*: GasCostKind
|
||||||
of GckInvalidOp:
|
of GckInvalidOp:
|
||||||
discard
|
discard
|
||||||
of GckFixed:
|
of GckFixed, GckLater:
|
||||||
cost*: GasInt
|
cost*: GasInt
|
||||||
of GckDynamic:
|
of GckDynamic:
|
||||||
d_handler*: proc(value: UInt256): GasInt
|
d_handler*: proc(value: UInt256): GasInt
|
||||||
@ -535,6 +536,13 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
|||||||
func fixed(gasFeeKind: static[GasFeeKind]): GasCost =
|
func fixed(gasFeeKind: static[GasFeeKind]): GasCost =
|
||||||
GasCost(kind: GckFixed, cost: static(FeeSchedule[gasFeeKind]))
|
GasCost(kind: GckFixed, cost: static(FeeSchedule[gasFeeKind]))
|
||||||
|
|
||||||
|
func fixedOrLater(gasFeeKind: static[GasFeeKind]): GasCost =
|
||||||
|
when fork < FkBerlin:
|
||||||
|
GasCost(kind: GckFixed, cost: static(FeeSchedule[gasFeeKind]))
|
||||||
|
else:
|
||||||
|
# GckLater is processed by the opcode
|
||||||
|
GasCost(kind: GckLater, cost: static(FeeSchedule[gasFeeKind]))
|
||||||
|
|
||||||
func dynamic(handler: proc(value: UInt256): GasInt
|
func dynamic(handler: proc(value: UInt256): GasInt
|
||||||
{.nimcall, gcsafe, raises: [CatchableError].}): GasCost =
|
{.nimcall, gcsafe, raises: [CatchableError].}): GasCost =
|
||||||
GasCost(kind: GckDynamic, d_handler: handler)
|
GasCost(kind: GckDynamic, d_handler: handler)
|
||||||
@ -585,7 +593,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
|||||||
|
|
||||||
# 30s: Environmental Information
|
# 30s: Environmental Information
|
||||||
Address: fixed GasBase,
|
Address: fixed GasBase,
|
||||||
Balance: fixed GasBalance,
|
Balance: fixedOrLater GasBalance,
|
||||||
Origin: fixed GasBase,
|
Origin: fixed GasBase,
|
||||||
Caller: fixed GasBase,
|
Caller: fixed GasBase,
|
||||||
CallValue: fixed GasBase,
|
CallValue: fixed GasBase,
|
||||||
@ -595,11 +603,11 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
|||||||
CodeSize: fixed GasBase,
|
CodeSize: fixed GasBase,
|
||||||
CodeCopy: memExpansion `prefix gasCopy`,
|
CodeCopy: memExpansion `prefix gasCopy`,
|
||||||
GasPrice: fixed GasBase,
|
GasPrice: fixed GasBase,
|
||||||
ExtCodeSize: fixed GasExtCode,
|
ExtCodeSize: fixedOrLater GasExtCode,
|
||||||
ExtCodeCopy: memExpansion `prefix gasExtCodeCopy`,
|
ExtCodeCopy: memExpansion `prefix gasExtCodeCopy`,
|
||||||
ReturnDataSize: fixed GasBase,
|
ReturnDataSize: fixed GasBase,
|
||||||
ReturnDataCopy: memExpansion `prefix gasCopy`,
|
ReturnDataCopy: memExpansion `prefix gasCopy`,
|
||||||
ExtCodeHash: fixed GasExtCodeHash,
|
ExtCodeHash: fixedOrLater GasExtCodeHash,
|
||||||
|
|
||||||
# 40s: Block Information
|
# 40s: Block Information
|
||||||
Blockhash: fixed GasBlockhash,
|
Blockhash: fixed GasBlockhash,
|
||||||
@ -618,7 +626,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
|||||||
Mload: memExpansion `prefix gasLoadStore`,
|
Mload: memExpansion `prefix gasLoadStore`,
|
||||||
Mstore: memExpansion `prefix gasLoadStore`,
|
Mstore: memExpansion `prefix gasLoadStore`,
|
||||||
Mstore8: memExpansion `prefix gasLoadStore`,
|
Mstore8: memExpansion `prefix gasLoadStore`,
|
||||||
Sload: fixed GasSload,
|
Sload: fixedOrLater GasSload,
|
||||||
Sstore: complex `prefix gasSstore`,
|
Sstore: complex `prefix gasSstore`,
|
||||||
Jump: fixed GasMid,
|
Jump: fixed GasMid,
|
||||||
JumpI: fixed GasHigh,
|
JumpI: fixed GasHigh,
|
||||||
|
@ -47,7 +47,7 @@ template handleFixedGasCostsDirective(fork: EVMFork; op: Op; k: var Vm2Ctx) =
|
|||||||
if k.cpt.tracingEnabled:
|
if k.cpt.tracingEnabled:
|
||||||
k.cpt.opIndex = k.cpt.traceOpCodeStarted(op)
|
k.cpt.opIndex = k.cpt.traceOpCodeStarted(op)
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(k.cpt.gasCosts[op].cost, reason = $op)
|
k.cpt.opcodeGastCost(op, k.cpt.gasCosts[op].cost, reason = $op)
|
||||||
vmOpHandlers[fork][op].run(k)
|
vmOpHandlers[fork][op].run(k)
|
||||||
|
|
||||||
# If continuation is not nil, traceOpCodeEnded will be called in executeOpcodes.
|
# If continuation is not nil, traceOpCodeEnded will be called in executeOpcodes.
|
||||||
|
@ -20,7 +20,6 @@ import
|
|||||||
../../types,
|
../../types,
|
||||||
../op_codes,
|
../op_codes,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
../utils/utils_numeric,
|
../utils/utils_numeric,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
eth/common
|
eth/common
|
||||||
@ -131,7 +130,7 @@ const
|
|||||||
## 0x0A, Exponentiation
|
## 0x0A, Exponentiation
|
||||||
let (base, exponent) = k.cpt.stack.popInt(2)
|
let (base, exponent) = k.cpt.stack.popInt(2)
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Exp,
|
||||||
k.cpt.gasCosts[Exp].d_handler(exponent),
|
k.cpt.gasCosts[Exp].d_handler(exponent),
|
||||||
reason = "EXP: exponent bytes")
|
reason = "EXP: exponent bytes")
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ type
|
|||||||
memOffset: int
|
memOffset: int
|
||||||
memLength: int
|
memLength: int
|
||||||
contractAddress: EthAddress
|
contractAddress: EthAddress
|
||||||
|
gasCallEIP2929: GasInt
|
||||||
|
|
||||||
|
|
||||||
proc updateStackAndParams(q: var LocalParams; c: Computation) =
|
proc updateStackAndParams(q: var LocalParams; c: Computation) =
|
||||||
@ -79,9 +80,7 @@ proc updateStackAndParams(q: var LocalParams; c: Computation) =
|
|||||||
if FkBerlin <= c.fork:
|
if FkBerlin <= c.fork:
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
if c.host.accessAccount(q.codeAddress) == EVMC_ACCESS_COLD:
|
if c.host.accessAccount(q.codeAddress) == EVMC_ACCESS_COLD:
|
||||||
c.gasMeter.consumeGas(
|
q.gasCallEIP2929 = ColdAccountAccessCost - WarmStorageReadCost
|
||||||
ColdAccountAccessCost - WarmStorageReadCost,
|
|
||||||
reason = "EIP2929 gasCall")
|
|
||||||
else:
|
else:
|
||||||
c.vmState.mutateStateDB:
|
c.vmState.mutateStateDB:
|
||||||
if not db.inAccessList(q.codeAddress):
|
if not db.inAccessList(q.codeAddress):
|
||||||
@ -89,9 +88,7 @@ proc updateStackAndParams(q: var LocalParams; c: Computation) =
|
|||||||
|
|
||||||
# The WarmStorageReadCostEIP2929 (100) is already deducted in
|
# The WarmStorageReadCostEIP2929 (100) is already deducted in
|
||||||
# the form of a constant `gasCall`
|
# the form of a constant `gasCall`
|
||||||
c.gasMeter.consumeGas(
|
q.gasCallEIP2929 = ColdAccountAccessCost - WarmStorageReadCost
|
||||||
ColdAccountAccessCost - WarmStorageReadCost,
|
|
||||||
reason = "EIP2929 gasCall")
|
|
||||||
|
|
||||||
|
|
||||||
proc callParams(c: Computation): LocalParams =
|
proc callParams(c: Computation): LocalParams =
|
||||||
@ -205,7 +202,6 @@ const
|
|||||||
"Cannot modify state while inside of a STATICCALL context")
|
"Cannot modify state while inside of a STATICCALL context")
|
||||||
|
|
||||||
let
|
let
|
||||||
gasAtStart = cpt.gasMeter.gasRemaining
|
|
||||||
p = cpt.callParams
|
p = cpt.callParams
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
||||||
@ -215,17 +211,15 @@ const
|
|||||||
GasParams(
|
GasParams(
|
||||||
kind: Call,
|
kind: Call,
|
||||||
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
||||||
c_gasBalance: cpt.gasMeter.gasRemaining,
|
c_gasBalance: cpt.gasMeter.gasRemaining - p.gasCallEIP2929,
|
||||||
c_contractGas: p.gas,
|
c_contractGas: p.gas,
|
||||||
c_currentMemSize: cpt.memory.len,
|
c_currentMemSize: cpt.memory.len,
|
||||||
c_memOffset: p.memOffset,
|
c_memOffset: p.memOffset,
|
||||||
c_memLength: p.memLength))
|
c_memLength: p.memLength))
|
||||||
|
|
||||||
# EIP 2046: temporary disabled
|
gasCost += p.gasCallEIP2929
|
||||||
# reduce gas fee for precompiles
|
|
||||||
# from 700 to 40
|
|
||||||
if gasCost >= 0:
|
if gasCost >= 0:
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = $Call)
|
cpt.opcodeGastCost(Call, gasCost, reason = $Call)
|
||||||
|
|
||||||
cpt.returnData.setLen(0)
|
cpt.returnData.setLen(0)
|
||||||
|
|
||||||
@ -241,17 +235,11 @@ const
|
|||||||
raise newException(
|
raise newException(
|
||||||
OutOfGas, "Gas not enough to perform calculation (call)")
|
OutOfGas, "Gas not enough to perform calculation (call)")
|
||||||
|
|
||||||
gasCost = gasAtStart - cpt.gasMeter.gasRemaining
|
|
||||||
cpt.traceCallFamilyGas(Call, gasCost)
|
|
||||||
|
|
||||||
cpt.memory.extend(p.memInPos, p.memInLen)
|
cpt.memory.extend(p.memInPos, p.memInLen)
|
||||||
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
||||||
|
|
||||||
let senderBalance = cpt.getBalance(p.sender)
|
let senderBalance = cpt.getBalance(p.sender)
|
||||||
if senderBalance < p.value:
|
if senderBalance < p.value:
|
||||||
#debug "Insufficient funds",
|
|
||||||
# available = senderBalance,
|
|
||||||
# needed = cpt.msg.value
|
|
||||||
cpt.gasMeter.returnGas(childGasLimit)
|
cpt.gasMeter.returnGas(childGasLimit)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -293,7 +281,6 @@ const
|
|||||||
## 0xf2, Message-call into this account with an alternative account's code.
|
## 0xf2, Message-call into this account with an alternative account's code.
|
||||||
let
|
let
|
||||||
cpt = k.cpt
|
cpt = k.cpt
|
||||||
gasAtStart = cpt.gasMeter.gasRemaining
|
|
||||||
p = cpt.callCodeParams
|
p = cpt.callCodeParams
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
||||||
@ -303,17 +290,15 @@ const
|
|||||||
GasParams(
|
GasParams(
|
||||||
kind: CallCode,
|
kind: CallCode,
|
||||||
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
||||||
c_gasBalance: cpt.gasMeter.gasRemaining,
|
c_gasBalance: cpt.gasMeter.gasRemaining - p.gasCallEIP2929,
|
||||||
c_contractGas: p.gas,
|
c_contractGas: p.gas,
|
||||||
c_currentMemSize: cpt.memory.len,
|
c_currentMemSize: cpt.memory.len,
|
||||||
c_memOffset: p.memOffset,
|
c_memOffset: p.memOffset,
|
||||||
c_memLength: p.memLength))
|
c_memLength: p.memLength))
|
||||||
|
|
||||||
# EIP 2046: temporary disabled
|
gasCost += p.gasCallEIP2929
|
||||||
# reduce gas fee for precompiles
|
|
||||||
# from 700 to 40
|
|
||||||
if gasCost >= 0:
|
if gasCost >= 0:
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = $CallCode)
|
cpt.opcodeGastCost(CallCode, gasCost, reason = $CallCode)
|
||||||
|
|
||||||
cpt.returnData.setLen(0)
|
cpt.returnData.setLen(0)
|
||||||
|
|
||||||
@ -325,24 +310,15 @@ const
|
|||||||
cpt.gasMeter.returnGas(childGasLimit)
|
cpt.gasMeter.returnGas(childGasLimit)
|
||||||
return
|
return
|
||||||
|
|
||||||
# EIP 2046: temporary disabled
|
|
||||||
# reduce gas fee for precompiles
|
|
||||||
# from 700 to 40
|
|
||||||
if gasCost < 0 and childGasLimit <= 0:
|
if gasCost < 0 and childGasLimit <= 0:
|
||||||
raise newException(
|
raise newException(
|
||||||
OutOfGas, "Gas not enough to perform calculation (callCode)")
|
OutOfGas, "Gas not enough to perform calculation (callCode)")
|
||||||
|
|
||||||
gasCost = gasAtStart - cpt.gasMeter.gasRemaining
|
|
||||||
cpt.traceCallFamilyGas(CallCode, gasCost)
|
|
||||||
|
|
||||||
cpt.memory.extend(p.memInPos, p.memInLen)
|
cpt.memory.extend(p.memInPos, p.memInLen)
|
||||||
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
||||||
|
|
||||||
let senderBalance = cpt.getBalance(p.sender)
|
let senderBalance = cpt.getBalance(p.sender)
|
||||||
if senderBalance < p.value:
|
if senderBalance < p.value:
|
||||||
#debug "Insufficient funds",
|
|
||||||
# available = senderBalance,
|
|
||||||
# needed = cpt.msg.value
|
|
||||||
cpt.gasMeter.returnGas(childGasLimit)
|
cpt.gasMeter.returnGas(childGasLimit)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -385,7 +361,6 @@ const
|
|||||||
## code, but persisting the current values for sender and value.
|
## code, but persisting the current values for sender and value.
|
||||||
let
|
let
|
||||||
cpt = k.cpt
|
cpt = k.cpt
|
||||||
gasAtStart = cpt.gasMeter.gasRemaining
|
|
||||||
p = cpt.delegateCallParams
|
p = cpt.delegateCallParams
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
||||||
@ -395,17 +370,15 @@ const
|
|||||||
GasParams(
|
GasParams(
|
||||||
kind: DelegateCall,
|
kind: DelegateCall,
|
||||||
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
||||||
c_gasBalance: cpt.gasMeter.gasRemaining,
|
c_gasBalance: cpt.gasMeter.gasRemaining - p.gasCallEIP2929,
|
||||||
c_contractGas: p.gas,
|
c_contractGas: p.gas,
|
||||||
c_currentMemSize: cpt.memory.len,
|
c_currentMemSize: cpt.memory.len,
|
||||||
c_memOffset: p.memOffset,
|
c_memOffset: p.memOffset,
|
||||||
c_memLength: p.memLength))
|
c_memLength: p.memLength))
|
||||||
|
|
||||||
# EIP 2046: temporary disabled
|
gasCost += p.gasCallEIP2929
|
||||||
# reduce gas fee for precompiles
|
|
||||||
# from 700 to 40
|
|
||||||
if gasCost >= 0:
|
if gasCost >= 0:
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = $DelegateCall)
|
cpt.opcodeGastCost(DelegateCall, gasCost, reason = $DelegateCall)
|
||||||
|
|
||||||
cpt.returnData.setLen(0)
|
cpt.returnData.setLen(0)
|
||||||
if cpt.msg.depth >= MaxCallDepth:
|
if cpt.msg.depth >= MaxCallDepth:
|
||||||
@ -420,9 +393,6 @@ const
|
|||||||
raise newException(
|
raise newException(
|
||||||
OutOfGas, "Gas not enough to perform calculation (delegateCall)")
|
OutOfGas, "Gas not enough to perform calculation (delegateCall)")
|
||||||
|
|
||||||
gasCost = gasAtStart - cpt.gasMeter.gasRemaining
|
|
||||||
cpt.traceCallFamilyGas(DelegateCall, gasCost)
|
|
||||||
|
|
||||||
cpt.memory.extend(p.memInPos, p.memInLen)
|
cpt.memory.extend(p.memInPos, p.memInLen)
|
||||||
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
||||||
|
|
||||||
@ -465,7 +435,6 @@ const
|
|||||||
|
|
||||||
let
|
let
|
||||||
cpt = k.cpt
|
cpt = k.cpt
|
||||||
gasAtStart = cpt.gasMeter.gasRemaining
|
|
||||||
p = cpt.staticCallParams
|
p = cpt.staticCallParams
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
cpt.asyncChainTo(ifNecessaryGetAccounts(cpt.vmState, @[p.sender])):
|
||||||
@ -475,21 +444,15 @@ const
|
|||||||
GasParams(
|
GasParams(
|
||||||
kind: StaticCall,
|
kind: StaticCall,
|
||||||
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
c_isNewAccount: not cpt.accountExists(p.contractAddress),
|
||||||
c_gasBalance: cpt.gasMeter.gasRemaining,
|
c_gasBalance: cpt.gasMeter.gasRemaining - p.gasCallEIP2929,
|
||||||
c_contractGas: p.gas,
|
c_contractGas: p.gas,
|
||||||
c_currentMemSize: cpt.memory.len,
|
c_currentMemSize: cpt.memory.len,
|
||||||
c_memOffset: p.memOffset,
|
c_memOffset: p.memOffset,
|
||||||
c_memLength: p.memLength))
|
c_memLength: p.memLength))
|
||||||
|
|
||||||
# EIP 2046: temporary disabled
|
gasCost += p.gasCallEIP2929
|
||||||
# reduce gas fee for precompiles
|
|
||||||
# from 700 to 40
|
|
||||||
#
|
|
||||||
# when opCode == StaticCall:
|
|
||||||
# if cpt.fork >= FkBerlin and codeAddress.toInt <= MaxPrecompilesAddr:
|
|
||||||
# gasCost = gasCost - 660.GasInt
|
|
||||||
if gasCost >= 0:
|
if gasCost >= 0:
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = $StaticCall)
|
cpt.opcodeGastCost(StaticCall, gasCost, reason = $StaticCall)
|
||||||
|
|
||||||
cpt.returnData.setLen(0)
|
cpt.returnData.setLen(0)
|
||||||
|
|
||||||
@ -505,9 +468,6 @@ const
|
|||||||
raise newException(
|
raise newException(
|
||||||
OutOfGas, "Gas not enough to perform calculation (staticCall)")
|
OutOfGas, "Gas not enough to perform calculation (staticCall)")
|
||||||
|
|
||||||
gasCost = gasAtStart - cpt.gasMeter.gasRemaining
|
|
||||||
cpt.traceCallFamilyGas(StaticCall, gasCost)
|
|
||||||
|
|
||||||
cpt.memory.extend(p.memInPos, p.memInLen)
|
cpt.memory.extend(p.memInPos, p.memInLen)
|
||||||
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
cpt.memory.extend(p.memOutPos, p.memOutLen)
|
||||||
|
|
||||||
|
@ -87,41 +87,42 @@ const
|
|||||||
checkInStaticContext(k.cpt)
|
checkInStaticContext(k.cpt)
|
||||||
|
|
||||||
let
|
let
|
||||||
endowment = k.cpt.stack.popInt()
|
cpt = k.cpt
|
||||||
memPos = k.cpt.stack.popInt().safeInt
|
endowment = cpt.stack.popInt()
|
||||||
memLen = k.cpt.stack.peekInt().safeInt
|
memPos = cpt.stack.popInt().safeInt
|
||||||
|
memLen = cpt.stack.peekInt().safeInt
|
||||||
|
|
||||||
k.cpt.stack.top(0)
|
cpt.stack.top(0)
|
||||||
|
|
||||||
# EIP-3860
|
# EIP-3860
|
||||||
if k.cpt.fork >= FkShanghai and memLen > EIP3860_MAX_INITCODE_SIZE:
|
if cpt.fork >= FkShanghai and memLen > EIP3860_MAX_INITCODE_SIZE:
|
||||||
trace "Initcode size exceeds maximum", initcodeSize = memLen
|
trace "Initcode size exceeds maximum", initcodeSize = memLen
|
||||||
raise newException(InitcodeError,
|
raise newException(InitcodeError,
|
||||||
&"CREATE: have {memLen}, max {EIP3860_MAX_INITCODE_SIZE}")
|
&"CREATE: have {memLen}, max {EIP3860_MAX_INITCODE_SIZE}")
|
||||||
|
|
||||||
let
|
let
|
||||||
gasAtStart = k.cpt.gasMeter.gasRemaining
|
|
||||||
gasParams = GasParams(
|
gasParams = GasParams(
|
||||||
kind: Create,
|
kind: Create,
|
||||||
cr_currentMemSize: k.cpt.memory.len,
|
cr_currentMemSize: cpt.memory.len,
|
||||||
cr_memOffset: memPos,
|
cr_memOffset: memPos,
|
||||||
cr_memLength: memLen)
|
cr_memLength: memLen)
|
||||||
|
|
||||||
var gasCost = k.cpt.gasCosts[Create].c_handler(1.u256, gasParams).gasCost
|
let gasCost = cpt.gasCosts[Create].c_handler(1.u256, gasParams).gasCost
|
||||||
k.cpt.gasMeter.consumeGas(
|
|
||||||
gasCost, reason = &"CREATE: GasCreate + {memLen} * memory expansion")
|
|
||||||
k.cpt.memory.extend(memPos, memLen)
|
|
||||||
k.cpt.returnData.setLen(0)
|
|
||||||
|
|
||||||
if k.cpt.msg.depth >= MaxCallDepth:
|
cpt.opcodeGastCost(Create,
|
||||||
|
gasCost, reason = &"CREATE: GasCreate + {memLen} * memory expansion")
|
||||||
|
cpt.memory.extend(memPos, memLen)
|
||||||
|
cpt.returnData.setLen(0)
|
||||||
|
|
||||||
|
if cpt.msg.depth >= MaxCallDepth:
|
||||||
debug "Computation Failure",
|
debug "Computation Failure",
|
||||||
reason = "Stack too deep",
|
reason = "Stack too deep",
|
||||||
maxDepth = MaxCallDepth,
|
maxDepth = MaxCallDepth,
|
||||||
depth = k.cpt.msg.depth
|
depth = cpt.msg.depth
|
||||||
return
|
return
|
||||||
|
|
||||||
if endowment != 0:
|
if endowment != 0:
|
||||||
let senderBalance = k.cpt.getBalance(k.cpt.msg.contractAddress)
|
let senderBalance = cpt.getBalance(cpt.msg.contractAddress)
|
||||||
if senderBalance < endowment:
|
if senderBalance < endowment:
|
||||||
debug "Computation Failure",
|
debug "Computation Failure",
|
||||||
reason = "Insufficient funds available to transfer",
|
reason = "Insufficient funds available to transfer",
|
||||||
@ -129,38 +130,35 @@ const
|
|||||||
balance = senderBalance
|
balance = senderBalance
|
||||||
return
|
return
|
||||||
|
|
||||||
var createMsgGas = k.cpt.gasMeter.gasRemaining
|
var createMsgGas = cpt.gasMeter.gasRemaining
|
||||||
if k.cpt.fork >= FkTangerine:
|
if cpt.fork >= FkTangerine:
|
||||||
createMsgGas -= createMsgGas div 64
|
createMsgGas -= createMsgGas div 64
|
||||||
k.cpt.gasMeter.consumeGas(createMsgGas, reason = "CREATE")
|
cpt.gasMeter.consumeGas(createMsgGas, reason = "CREATE msg gas")
|
||||||
|
|
||||||
gasCost = gasAtStart - k.cpt.gasMeter.gasRemaining
|
|
||||||
k.cpt.traceCallFamilyGas(Create, gasCost)
|
|
||||||
|
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
let
|
let
|
||||||
msg = new(nimbus_message)
|
msg = new(nimbus_message)
|
||||||
c = k.cpt
|
c = cpt
|
||||||
msg[] = nimbus_message(
|
msg[] = nimbus_message(
|
||||||
kind: evmcCreate.ord.evmc_call_kind,
|
kind: evmcCreate.ord.evmc_call_kind,
|
||||||
depth: (k.cpt.msg.depth + 1).int32,
|
depth: (cpt.msg.depth + 1).int32,
|
||||||
gas: createMsgGas,
|
gas: createMsgGas,
|
||||||
sender: k.cpt.msg.contractAddress,
|
sender: cpt.msg.contractAddress,
|
||||||
input_data: k.cpt.memory.readPtr(memPos),
|
input_data: cpt.memory.readPtr(memPos),
|
||||||
input_size: memLen.uint,
|
input_size: memLen.uint,
|
||||||
value: toEvmc(endowment),
|
value: toEvmc(endowment),
|
||||||
create2_salt: toEvmc(ZERO_CONTRACTSALT),
|
create2_salt: toEvmc(ZERO_CONTRACTSALT),
|
||||||
)
|
)
|
||||||
c.execSubCreate(msg)
|
c.execSubCreate(msg)
|
||||||
else:
|
else:
|
||||||
k.cpt.execSubCreate(
|
cpt.execSubCreate(
|
||||||
childMsg = Message(
|
childMsg = Message(
|
||||||
kind: evmcCreate,
|
kind: evmcCreate,
|
||||||
depth: k.cpt.msg.depth + 1,
|
depth: cpt.msg.depth + 1,
|
||||||
gas: createMsgGas,
|
gas: createMsgGas,
|
||||||
sender: k.cpt.msg.contractAddress,
|
sender: cpt.msg.contractAddress,
|
||||||
value: endowment,
|
value: endowment,
|
||||||
data: k.cpt.memory.read(memPos, memLen)))
|
data: cpt.memory.read(memPos, memLen)))
|
||||||
|
|
||||||
# ---------------------
|
# ---------------------
|
||||||
|
|
||||||
@ -169,44 +167,44 @@ const
|
|||||||
checkInStaticContext(k.cpt)
|
checkInStaticContext(k.cpt)
|
||||||
|
|
||||||
let
|
let
|
||||||
endowment = k.cpt.stack.popInt()
|
cpt = k.cpt
|
||||||
memPos = k.cpt.stack.popInt().safeInt
|
endowment = cpt.stack.popInt()
|
||||||
memLen = k.cpt.stack.popInt().safeInt
|
memPos = cpt.stack.popInt().safeInt
|
||||||
salt = ContractSalt(bytes: k.cpt.stack.peekInt().toBytesBE)
|
memLen = cpt.stack.popInt().safeInt
|
||||||
|
salt = ContractSalt(bytes: cpt.stack.peekInt().toBytesBE)
|
||||||
|
|
||||||
k.cpt.stack.top(0)
|
cpt.stack.top(0)
|
||||||
|
|
||||||
# EIP-3860
|
# EIP-3860
|
||||||
if k.cpt.fork >= FkShanghai and memLen > EIP3860_MAX_INITCODE_SIZE:
|
if cpt.fork >= FkShanghai and memLen > EIP3860_MAX_INITCODE_SIZE:
|
||||||
trace "Initcode size exceeds maximum", initcodeSize = memLen
|
trace "Initcode size exceeds maximum", initcodeSize = memLen
|
||||||
raise newException(InitcodeError,
|
raise newException(InitcodeError,
|
||||||
&"CREATE2: have {memLen}, max {EIP3860_MAX_INITCODE_SIZE}")
|
&"CREATE2: have {memLen}, max {EIP3860_MAX_INITCODE_SIZE}")
|
||||||
|
|
||||||
let
|
let
|
||||||
gasAtStart = k.cpt.gasMeter.gasRemaining
|
|
||||||
gasParams = GasParams(
|
gasParams = GasParams(
|
||||||
kind: Create,
|
kind: Create,
|
||||||
cr_currentMemSize: k.cpt.memory.len,
|
cr_currentMemSize: cpt.memory.len,
|
||||||
cr_memOffset: memPos,
|
cr_memOffset: memPos,
|
||||||
cr_memLength: memLen)
|
cr_memLength: memLen)
|
||||||
|
|
||||||
var gasCost = k.cpt.gasCosts[Create].c_handler(1.u256, gasParams).gasCost
|
var gasCost = cpt.gasCosts[Create].c_handler(1.u256, gasParams).gasCost
|
||||||
gasCost = gasCost + k.cpt.gasCosts[Create2].m_handler(0, 0, memLen)
|
gasCost = gasCost + cpt.gasCosts[Create2].m_handler(0, 0, memLen)
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(Create2,
|
||||||
gasCost, reason = &"CREATE2: GasCreate + {memLen} * memory expansion")
|
gasCost, reason = &"CREATE2: GasCreate + {memLen} * memory expansion")
|
||||||
k.cpt.memory.extend(memPos, memLen)
|
cpt.memory.extend(memPos, memLen)
|
||||||
k.cpt.returnData.setLen(0)
|
cpt.returnData.setLen(0)
|
||||||
|
|
||||||
if k.cpt.msg.depth >= MaxCallDepth:
|
if cpt.msg.depth >= MaxCallDepth:
|
||||||
debug "Computation Failure",
|
debug "Computation Failure",
|
||||||
reason = "Stack too deep",
|
reason = "Stack too deep",
|
||||||
maxDepth = MaxCallDepth,
|
maxDepth = MaxCallDepth,
|
||||||
depth = k.cpt.msg.depth
|
depth = cpt.msg.depth
|
||||||
return
|
return
|
||||||
|
|
||||||
if endowment != 0:
|
if endowment != 0:
|
||||||
let senderBalance = k.cpt.getBalance(k.cpt.msg.contractAddress)
|
let senderBalance = cpt.getBalance(cpt.msg.contractAddress)
|
||||||
if senderBalance < endowment:
|
if senderBalance < endowment:
|
||||||
debug "Computation Failure",
|
debug "Computation Failure",
|
||||||
reason = "Insufficient funds available to transfer",
|
reason = "Insufficient funds available to transfer",
|
||||||
@ -214,39 +212,36 @@ const
|
|||||||
balance = senderBalance
|
balance = senderBalance
|
||||||
return
|
return
|
||||||
|
|
||||||
var createMsgGas = k.cpt.gasMeter.gasRemaining
|
var createMsgGas = cpt.gasMeter.gasRemaining
|
||||||
if k.cpt.fork >= FkTangerine:
|
if cpt.fork >= FkTangerine:
|
||||||
createMsgGas -= createMsgGas div 64
|
createMsgGas -= createMsgGas div 64
|
||||||
k.cpt.gasMeter.consumeGas(createMsgGas, reason = "CREATE2")
|
cpt.gasMeter.consumeGas(createMsgGas, reason = "CREATE2 msg gas")
|
||||||
|
|
||||||
gasCost = gasAtStart - k.cpt.gasMeter.gasRemaining
|
|
||||||
k.cpt.traceCallFamilyGas(Create2, gasCost)
|
|
||||||
|
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
let
|
let
|
||||||
msg = new(nimbus_message)
|
msg = new(nimbus_message)
|
||||||
c = k.cpt
|
c = cpt
|
||||||
msg[] = nimbus_message(
|
msg[] = nimbus_message(
|
||||||
kind: evmcCreate2.ord.evmc_call_kind,
|
kind: evmcCreate2.ord.evmc_call_kind,
|
||||||
depth: (k.cpt.msg.depth + 1).int32,
|
depth: (cpt.msg.depth + 1).int32,
|
||||||
gas: createMsgGas,
|
gas: createMsgGas,
|
||||||
sender: k.cpt.msg.contractAddress,
|
sender: cpt.msg.contractAddress,
|
||||||
input_data: k.cpt.memory.readPtr(memPos),
|
input_data: cpt.memory.readPtr(memPos),
|
||||||
input_size: memLen.uint,
|
input_size: memLen.uint,
|
||||||
value: toEvmc(endowment),
|
value: toEvmc(endowment),
|
||||||
create2_salt: toEvmc(salt),
|
create2_salt: toEvmc(salt),
|
||||||
)
|
)
|
||||||
c.execSubCreate(msg)
|
c.execSubCreate(msg)
|
||||||
else:
|
else:
|
||||||
k.cpt.execSubCreate(
|
cpt.execSubCreate(
|
||||||
salt = salt,
|
salt = salt,
|
||||||
childMsg = Message(
|
childMsg = Message(
|
||||||
kind: evmcCreate2,
|
kind: evmcCreate2,
|
||||||
depth: k.cpt.msg.depth + 1,
|
depth: cpt.msg.depth + 1,
|
||||||
gas: createMsgGas,
|
gas: createMsgGas,
|
||||||
sender: k.cpt.msg.contractAddress,
|
sender: cpt.msg.contractAddress,
|
||||||
value: endowment,
|
value: endowment,
|
||||||
data: k.cpt.memory.read(memPos, memLen)))
|
data: cpt.memory.read(memPos, memLen)))
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public, op exec table entries
|
# Public, op exec table entries
|
||||||
|
@ -20,7 +20,6 @@ import
|
|||||||
../../stack,
|
../../stack,
|
||||||
../../async/operations,
|
../../async/operations,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
../op_codes,
|
../op_codes,
|
||||||
../utils/utils_numeric,
|
../utils/utils_numeric,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
@ -84,7 +83,8 @@ const
|
|||||||
let address = cpt.stack.popAddress()
|
let address = cpt.stack.popAddress()
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetAccount(cpt.vmState, address)):
|
cpt.asyncChainTo(ifNecessaryGetAccount(cpt.vmState, address)):
|
||||||
cpt.gasEip2929AccountCheck(address)
|
let gasCost = cpt.gasCosts[Balance].cost + cpt.gasEip2929AccountCheck(address)
|
||||||
|
cpt.opcodeGastCost(Balance, gasCost, reason = "Balance EIP2929")
|
||||||
cpt.stack.push:
|
cpt.stack.push:
|
||||||
cpt.getBalance(address)
|
cpt.getBalance(address)
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ const
|
|||||||
let (memPos, copyPos, len) =
|
let (memPos, copyPos, len) =
|
||||||
(memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
|
(memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(CallDataCopy,
|
||||||
k.cpt.gasCosts[CallDataCopy].m_handler(k.cpt.memory.len, memPos, len),
|
k.cpt.gasCosts[CallDataCopy].m_handler(k.cpt.memory.len, memPos, len),
|
||||||
reason = "CallDataCopy fee")
|
reason = "CallDataCopy fee")
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ const
|
|||||||
let (memPos, copyPos, len) =
|
let (memPos, copyPos, len) =
|
||||||
(memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
|
(memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
|
||||||
|
|
||||||
cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(CodeCopy,
|
||||||
cpt.gasCosts[CodeCopy].m_handler(cpt.memory.len, memPos, len),
|
cpt.gasCosts[CodeCopy].m_handler(cpt.memory.len, memPos, len),
|
||||||
reason = "CodeCopy fee")
|
reason = "CodeCopy fee")
|
||||||
|
|
||||||
@ -193,7 +193,8 @@ const
|
|||||||
let address = cpt.stack.popAddress()
|
let address = cpt.stack.popAddress()
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetCode(cpt.vmState, address)):
|
cpt.asyncChainTo(ifNecessaryGetCode(cpt.vmState, address)):
|
||||||
cpt.gasEip2929AccountCheck(address)
|
let gasCost = cpt.gasCosts[ExtCodeSize].cost + cpt.gasEip2929AccountCheck(address)
|
||||||
|
cpt.opcodeGastCost(ExtCodeSize, gasCost, reason = "ExtCodeSize EIP2929")
|
||||||
cpt.stack.push:
|
cpt.stack.push:
|
||||||
cpt.getCodeSize(address)
|
cpt.getCodeSize(address)
|
||||||
|
|
||||||
@ -209,7 +210,7 @@ const
|
|||||||
let (memPos, codePos, len) =
|
let (memPos, codePos, len) =
|
||||||
(memStartPos.cleanMemRef, codeStartPos.cleanMemRef, size.cleanMemRef)
|
(memStartPos.cleanMemRef, codeStartPos.cleanMemRef, size.cleanMemRef)
|
||||||
|
|
||||||
cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(ExtCodeCopy,
|
||||||
cpt.gasCosts[ExtCodeCopy].m_handler(cpt.memory.len, memPos, len),
|
cpt.gasCosts[ExtCodeCopy].m_handler(cpt.memory.len, memPos, len),
|
||||||
reason = "ExtCodeCopy fee")
|
reason = "ExtCodeCopy fee")
|
||||||
|
|
||||||
@ -226,11 +227,10 @@ const
|
|||||||
let (memStartPos, codeStartPos, size) = cpt.stack.popInt(3)
|
let (memStartPos, codeStartPos, size) = cpt.stack.popInt(3)
|
||||||
let (memPos, codePos, len) = (memStartPos.cleanMemRef,
|
let (memPos, codePos, len) = (memStartPos.cleanMemRef,
|
||||||
codeStartPos.cleanMemRef, size.cleanMemRef)
|
codeStartPos.cleanMemRef, size.cleanMemRef)
|
||||||
cpt.gasMeter.consumeGas(
|
|
||||||
cpt.gasCosts[ExtCodeCopy].m_handler(cpt.memory.len, memPos, len),
|
|
||||||
reason = "ExtCodeCopy fee")
|
|
||||||
|
|
||||||
|
let gasCost = cpt.gasCosts[ExtCodeCopy].m_handler(cpt.memory.len, memPos, len) +
|
||||||
cpt.gasEip2929AccountCheck(address)
|
cpt.gasEip2929AccountCheck(address)
|
||||||
|
cpt.opcodeGastCost(ExtCodeCopy, gasCost, reason = "ExtCodeCopy EIP2929")
|
||||||
|
|
||||||
let codeBytes = cpt.getCode(address)
|
let codeBytes = cpt.getCode(address)
|
||||||
cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
||||||
@ -253,7 +253,7 @@ const
|
|||||||
|
|
||||||
let gasCost = k.cpt.gasCosts[ReturnDataCopy].m_handler(
|
let gasCost = k.cpt.gasCosts[ReturnDataCopy].m_handler(
|
||||||
k.cpt.memory.len, memPos, len)
|
k.cpt.memory.len, memPos, len)
|
||||||
k.cpt.gasMeter.consumeGas(gasCost, reason = "returnDataCopy fee")
|
k.cpt.opcodeGastCost(ReturnDataCopy, gasCost, reason = "returnDataCopy fee")
|
||||||
|
|
||||||
if copyPos + len > k.cpt.returnData.len:
|
if copyPos + len > k.cpt.returnData.len:
|
||||||
raise newException(
|
raise newException(
|
||||||
@ -280,7 +280,8 @@ const
|
|||||||
let address = k.cpt.stack.popAddress()
|
let address = k.cpt.stack.popAddress()
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetCode(cpt.vmState, address)):
|
cpt.asyncChainTo(ifNecessaryGetCode(cpt.vmState, address)):
|
||||||
cpt.gasEip2929AccountCheck(address)
|
let gasCost = cpt.gasCosts[ExtCodeHash].cost + cpt.gasEip2929AccountCheck(address)
|
||||||
|
cpt.opcodeGastCost(ExtCodeHash, gasCost, reason = "ExtCodeHash EIP2929")
|
||||||
|
|
||||||
cpt.stack.push:
|
cpt.stack.push:
|
||||||
cpt.getCodeHash(address)
|
cpt.getCodeHash(address)
|
||||||
|
@ -19,7 +19,6 @@ import
|
|||||||
../../memory,
|
../../memory,
|
||||||
../../stack,
|
../../stack,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
../op_codes,
|
../op_codes,
|
||||||
../utils/utils_numeric,
|
../utils/utils_numeric,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
@ -40,7 +39,7 @@ const
|
|||||||
if pos < 0 or len < 0 or pos > 2147483648'i64:
|
if pos < 0 or len < 0 or pos > 2147483648'i64:
|
||||||
raise newException(OutOfBoundsRead, "Out of bounds memory access")
|
raise newException(OutOfBoundsRead, "Out of bounds memory access")
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Op.Sha3,
|
||||||
k.cpt.gasCosts[Op.Sha3].m_handler(k.cpt.memory.len, pos, len),
|
k.cpt.gasCosts[Op.Sha3].m_handler(k.cpt.memory.len, pos, len),
|
||||||
reason = "SHA3: word gas cost")
|
reason = "SHA3: word gas cost")
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ import
|
|||||||
../../../errors,
|
../../../errors,
|
||||||
../../types,
|
../../types,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
eth/common,
|
eth/common,
|
||||||
eth/common/eth_types,
|
eth/common/eth_types,
|
||||||
macros,
|
macros,
|
||||||
@ -35,26 +34,33 @@ else:
|
|||||||
# Public
|
# Public
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc gasEip2929AccountCheck*(c: Computation; address: EthAddress) =
|
proc gasEip2929AccountCheck*(c: Computation; address: EthAddress): GasInt =
|
||||||
when defined(evmc_enabled):
|
when defined(evmc_enabled):
|
||||||
let gasCost = if c.host.accessAccount(address) == EVMC_ACCESS_COLD:
|
result = if c.host.accessAccount(address) == EVMC_ACCESS_COLD:
|
||||||
ColdAccountAccessCost
|
ColdAccountAccessCost
|
||||||
else:
|
else:
|
||||||
WarmStorageReadCost
|
WarmStorageReadCost
|
||||||
c.gasMeter.consumeGas(
|
|
||||||
gasCost,
|
|
||||||
reason = "gasEIP2929AccountCheck")
|
|
||||||
else:
|
else:
|
||||||
c.vmState.mutateStateDB:
|
c.vmState.mutateStateDB:
|
||||||
let gasCost = if not db.inAccessList(address):
|
result = if not db.inAccessList(address):
|
||||||
db.accessList(address)
|
db.accessList(address)
|
||||||
ColdAccountAccessCost
|
ColdAccountAccessCost
|
||||||
else:
|
else:
|
||||||
WarmStorageReadCost
|
WarmStorageReadCost
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
proc gasEip2929AccountCheck*(c: Computation; address: EthAddress, slot: UInt256): GasInt =
|
||||||
gasCost,
|
when defined(evmc_enabled):
|
||||||
reason = "gasEIP2929AccountCheck")
|
result = if c.host.accessStorage(address, slot) == EVMC_ACCESS_COLD:
|
||||||
|
ColdSloadCost
|
||||||
|
else:
|
||||||
|
WarmStorageReadCost
|
||||||
|
else:
|
||||||
|
c.vmState.mutateStateDB:
|
||||||
|
result = if not db.inAccessList(address, slot):
|
||||||
|
db.accessList(address, slot)
|
||||||
|
ColdSloadCost
|
||||||
|
else:
|
||||||
|
WarmStorageReadCost
|
||||||
|
|
||||||
template checkInStaticContext*(c: Computation) =
|
template checkInStaticContext*(c: Computation) =
|
||||||
## Verify static context in handler function, raise an error otherwise
|
## Verify static context in handler function, raise an error otherwise
|
||||||
|
@ -20,7 +20,6 @@ import
|
|||||||
../../stack,
|
../../stack,
|
||||||
../../types,
|
../../types,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
../op_codes,
|
../op_codes,
|
||||||
../utils/utils_numeric,
|
../utils/utils_numeric,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
@ -59,7 +58,7 @@ proc logImpl(c: Computation, opcode: Op, topicCount: int) =
|
|||||||
if memPos < 0 or len < 0:
|
if memPos < 0 or len < 0:
|
||||||
raise newException(OutOfBoundsRead, "Out of bounds memory access")
|
raise newException(OutOfBoundsRead, "Out of bounds memory access")
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
c.opcodeGastCost(opcode,
|
||||||
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
|
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
|
||||||
reason = "Memory expansion, Log topic and data gas cost")
|
reason = "Memory expansion, Log topic and data gas cost")
|
||||||
c.memory.extend(memPos, len)
|
c.memory.extend(memPos, len)
|
||||||
|
@ -41,15 +41,14 @@ when not defined(evmc_enabled):
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
proc sstoreEvmc(c: Computation, slot, newValue: UInt256) =
|
proc sstoreEvmc(c: Computation, slot, newValue: UInt256, coldAccess = 0.GasInt) =
|
||||||
let
|
let
|
||||||
currentValue = c.getStorage(slot)
|
currentValue = c.getStorage(slot)
|
||||||
status = c.host.setStorage(c.msg.contractAddress, slot, newValue)
|
status = c.host.setStorage(c.msg.contractAddress, slot, newValue)
|
||||||
gasParam = GasParams(kind: Op.Sstore, s_status: status)
|
gasParam = GasParams(kind: Op.Sstore, s_status: status)
|
||||||
gasCost = c.gasCosts[Sstore].c_handler(newValue, gasParam)[0]
|
gasCost = c.gasCosts[Sstore].c_handler(newValue, gasParam)[0] + coldAccess
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
c.opcodeGastCost(Sstore, gasCost, "SSTORE")
|
||||||
gasCost, "SSTORE")
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc sstoreImpl(c: Computation, slot, newValue: UInt256) =
|
proc sstoreImpl(c: Computation, slot, newValue: UInt256) =
|
||||||
@ -62,8 +61,7 @@ else:
|
|||||||
(gasCost, gasRefund) =
|
(gasCost, gasRefund) =
|
||||||
c.gasCosts[Sstore].c_handler(newValue, gasParam)
|
c.gasCosts[Sstore].c_handler(newValue, gasParam)
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
c.opcodeGastCost(Sstore, gasCost, "SSTORE")
|
||||||
gasCost, "SSTORE")
|
|
||||||
if gasRefund > 0:
|
if gasRefund > 0:
|
||||||
c.gasMeter.refundGas(gasRefund)
|
c.gasMeter.refundGas(gasRefund)
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ else:
|
|||||||
db.setStorage(c.msg.contractAddress, slot, newValue)
|
db.setStorage(c.msg.contractAddress, slot, newValue)
|
||||||
|
|
||||||
|
|
||||||
proc sstoreNetGasMeteringImpl(c: Computation; slot, newValue: UInt256) =
|
proc sstoreNetGasMeteringImpl(c: Computation; slot, newValue: UInt256, coldAccess = 0.GasInt) =
|
||||||
let
|
let
|
||||||
stateDB = c.vmState.readOnlyStateDB
|
stateDB = c.vmState.readOnlyStateDB
|
||||||
currentValue = c.getStorage(slot)
|
currentValue = c.getStorage(slot)
|
||||||
@ -81,17 +79,21 @@ else:
|
|||||||
s_currentValue: currentValue,
|
s_currentValue: currentValue,
|
||||||
s_originalValue: stateDB.getCommittedStorage(c.msg.contractAddress, slot))
|
s_originalValue: stateDB.getCommittedStorage(c.msg.contractAddress, slot))
|
||||||
|
|
||||||
(gasCost, gasRefund) = c.gasCosts[Sstore].c_handler(newValue, gasParam)
|
res = c.gasCosts[Sstore].c_handler(newValue, gasParam)
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
c.opcodeGastCost(Sstore, res.gasCost + coldAccess, "SSTORE")
|
||||||
gasCost, "SSTORE EIP2200")
|
|
||||||
|
|
||||||
if gasRefund != 0:
|
if res.gasRefund != 0:
|
||||||
c.gasMeter.refundGas(gasRefund)
|
c.gasMeter.refundGas(res.gasRefund)
|
||||||
|
|
||||||
c.vmState.mutateStateDB:
|
c.vmState.mutateStateDB:
|
||||||
db.setStorage(c.msg.contractAddress, slot, newValue)
|
db.setStorage(c.msg.contractAddress, slot, newValue)
|
||||||
|
|
||||||
|
template sstoreEvmcOrNetGasMetering(cpt, slot, newValue: untyped, coldAccess = 0.GasInt) =
|
||||||
|
when evmc_enabled:
|
||||||
|
sstoreEvmc(cpt, slot, newValue, coldAccess)
|
||||||
|
else:
|
||||||
|
sstoreNetGasMeteringImpl(cpt, slot, newValue, coldAccess)
|
||||||
|
|
||||||
proc jumpImpl(c: Computation; jumpTarget: UInt256) =
|
proc jumpImpl(c: Computation; jumpTarget: UInt256) =
|
||||||
if jumpTarget >= c.code.len.u256:
|
if jumpTarget >= c.code.len.u256:
|
||||||
@ -124,7 +126,7 @@ const
|
|||||||
let (memStartPos) = k.cpt.stack.popInt(1)
|
let (memStartPos) = k.cpt.stack.popInt(1)
|
||||||
|
|
||||||
let memPos = memStartPos.cleanMemRef
|
let memPos = memStartPos.cleanMemRef
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Mload,
|
||||||
k.cpt.gasCosts[Mload].m_handler(k.cpt.memory.len, memPos, 32),
|
k.cpt.gasCosts[Mload].m_handler(k.cpt.memory.len, memPos, 32),
|
||||||
reason = "MLOAD: GasVeryLow + memory expansion")
|
reason = "MLOAD: GasVeryLow + memory expansion")
|
||||||
|
|
||||||
@ -138,7 +140,7 @@ const
|
|||||||
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
||||||
|
|
||||||
let memPos = memStartPos.cleanMemRef
|
let memPos = memStartPos.cleanMemRef
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Mstore,
|
||||||
k.cpt.gasCosts[Mstore].m_handler(k.cpt.memory.len, memPos, 32),
|
k.cpt.gasCosts[Mstore].m_handler(k.cpt.memory.len, memPos, 32),
|
||||||
reason = "MSTORE: GasVeryLow + memory expansion")
|
reason = "MSTORE: GasVeryLow + memory expansion")
|
||||||
|
|
||||||
@ -151,8 +153,8 @@ const
|
|||||||
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
||||||
|
|
||||||
let memPos = memStartPos.cleanMemRef
|
let memPos = memStartPos.cleanMemRef
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Mstore8,
|
||||||
k.cpt.gasCosts[Mstore].m_handler(k.cpt.memory.len, memPos, 1),
|
k.cpt.gasCosts[Mstore8].m_handler(k.cpt.memory.len, memPos, 1),
|
||||||
reason = "MSTORE8: GasVeryLow + memory expansion")
|
reason = "MSTORE8: GasVeryLow + memory expansion")
|
||||||
|
|
||||||
k.cpt.memory.extend(memPos, 1)
|
k.cpt.memory.extend(memPos, 1)
|
||||||
@ -174,20 +176,9 @@ const
|
|||||||
let (slot) = cpt.stack.popInt(1)
|
let (slot) = cpt.stack.popInt(1)
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
||||||
when evmc_enabled:
|
let gasCost = cpt.gasEip2929AccountCheck(cpt.msg.contractAddress, slot) +
|
||||||
let gasCost = if cpt.host.accessStorage(cpt.msg.contractAddress, slot) == EVMC_ACCESS_COLD:
|
cpt.gasCosts[Sload].cost
|
||||||
ColdSloadCost
|
cpt.opcodeGastCost(Sload, gasCost, reason = "sloadEIP2929")
|
||||||
else:
|
|
||||||
WarmStorageReadCost
|
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
|
||||||
else:
|
|
||||||
cpt.vmState.mutateStateDB:
|
|
||||||
let gasCost = if not db.inAccessList(cpt.msg.contractAddress, slot):
|
|
||||||
db.accessList(cpt.msg.contractAddress, slot)
|
|
||||||
ColdSloadCost
|
|
||||||
else:
|
|
||||||
WarmStorageReadCost
|
|
||||||
cpt.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
|
||||||
cpt.stack.push:
|
cpt.stack.push:
|
||||||
cpt.getStorage(slot)
|
cpt.getStorage(slot)
|
||||||
|
|
||||||
@ -200,10 +191,7 @@ const
|
|||||||
|
|
||||||
checkInStaticContext(cpt)
|
checkInStaticContext(cpt)
|
||||||
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
||||||
when evmc_enabled:
|
sstoreEvmcOrNetGasMetering(cpt, slot, newValue)
|
||||||
sstoreEvmc(cpt, slot, newValue)
|
|
||||||
else:
|
|
||||||
sstoreImpl(cpt, slot, newValue)
|
|
||||||
|
|
||||||
|
|
||||||
sstoreEIP1283Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
sstoreEIP1283Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||||
@ -213,10 +201,7 @@ const
|
|||||||
|
|
||||||
checkInStaticContext(cpt)
|
checkInStaticContext(cpt)
|
||||||
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
||||||
when evmc_enabled:
|
sstoreEvmcOrNetGasMetering(cpt, slot, newValue)
|
||||||
sstoreEvmc(cpt, slot, newValue)
|
|
||||||
else:
|
|
||||||
sstoreNetGasMeteringImpl(cpt, slot, newValue)
|
|
||||||
|
|
||||||
|
|
||||||
sstoreEIP2200Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
sstoreEIP2200Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||||
@ -233,10 +218,7 @@ const
|
|||||||
"Gas not enough to perform EIP2200 SSTORE")
|
"Gas not enough to perform EIP2200 SSTORE")
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
||||||
when evmc_enabled:
|
sstoreEvmcOrNetGasMetering(cpt, slot, newValue)
|
||||||
sstoreEvmc(cpt, slot, newValue)
|
|
||||||
else:
|
|
||||||
sstoreNetGasMeteringImpl(cpt, slot, newValue)
|
|
||||||
|
|
||||||
|
|
||||||
sstoreEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
sstoreEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||||
@ -252,19 +234,17 @@ const
|
|||||||
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
||||||
|
|
||||||
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
cpt.asyncChainTo(ifNecessaryGetSlot(cpt.vmState, cpt.msg.contractAddress, slot)):
|
||||||
|
var coldAccessGas = 0.GasInt
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
if cpt.host.accessStorage(cpt.msg.contractAddress, slot) == EVMC_ACCESS_COLD:
|
if cpt.host.accessStorage(cpt.msg.contractAddress, slot) == EVMC_ACCESS_COLD:
|
||||||
cpt.gasMeter.consumeGas(ColdSloadCost, reason = "sstoreEIP2929")
|
coldAccessGas = ColdSloadCost
|
||||||
else:
|
else:
|
||||||
cpt.vmState.mutateStateDB:
|
cpt.vmState.mutateStateDB:
|
||||||
if not db.inAccessList(cpt.msg.contractAddress, slot):
|
if not db.inAccessList(cpt.msg.contractAddress, slot):
|
||||||
db.accessList(cpt.msg.contractAddress, slot)
|
db.accessList(cpt.msg.contractAddress, slot)
|
||||||
cpt.gasMeter.consumeGas(ColdSloadCost, reason = "sstoreEIP2929")
|
coldAccessGas = ColdSloadCost
|
||||||
|
|
||||||
when evmc_enabled:
|
sstoreEvmcOrNetGasMetering(cpt, slot, newValue, coldAccessGas)
|
||||||
sstoreEvmc(cpt, slot, newValue)
|
|
||||||
else:
|
|
||||||
sstoreNetGasMeteringImpl(cpt, slot, newValue)
|
|
||||||
|
|
||||||
# -------
|
# -------
|
||||||
|
|
||||||
@ -324,7 +304,7 @@ const
|
|||||||
let (dstPos, srcPos, len) =
|
let (dstPos, srcPos, len) =
|
||||||
(dst.cleanMemRef, src.cleanMemRef, size.cleanMemRef)
|
(dst.cleanMemRef, src.cleanMemRef, size.cleanMemRef)
|
||||||
|
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Mcopy,
|
||||||
k.cpt.gasCosts[Mcopy].m_handler(k.cpt.memory.len, max(dstPos, srcPos), len),
|
k.cpt.gasCosts[Mcopy].m_handler(k.cpt.memory.len, max(dstPos, srcPos), len),
|
||||||
reason = "Mcopy fee")
|
reason = "Mcopy fee")
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import
|
|||||||
../../types,
|
../../types,
|
||||||
../../async/operations,
|
../../async/operations,
|
||||||
../gas_costs,
|
../gas_costs,
|
||||||
../gas_meter,
|
|
||||||
../op_codes,
|
../op_codes,
|
||||||
../utils/utils_numeric,
|
../utils/utils_numeric,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
@ -45,7 +44,7 @@ const
|
|||||||
let (startPos, size) = k.cpt.stack.popInt(2)
|
let (startPos, size) = k.cpt.stack.popInt(2)
|
||||||
|
|
||||||
let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
|
let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Return,
|
||||||
k.cpt.gasCosts[Return].m_handler(k.cpt.memory.len, pos, len),
|
k.cpt.gasCosts[Return].m_handler(k.cpt.memory.len, pos, len),
|
||||||
reason = "RETURN")
|
reason = "RETURN")
|
||||||
k.cpt.memory.extend(pos, len)
|
k.cpt.memory.extend(pos, len)
|
||||||
@ -58,7 +57,7 @@ const
|
|||||||
let (startPos, size) = k.cpt.stack.popInt(2)
|
let (startPos, size) = k.cpt.stack.popInt(2)
|
||||||
|
|
||||||
let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
|
let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
|
||||||
k.cpt.gasMeter.consumeGas(
|
k.cpt.opcodeGastCost(Revert,
|
||||||
k.cpt.gasCosts[Revert].m_handler(k.cpt.memory.len, pos, len),
|
k.cpt.gasCosts[Revert].m_handler(k.cpt.memory.len, pos, len),
|
||||||
reason = "REVERT")
|
reason = "REVERT")
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ const
|
|||||||
|
|
||||||
let gasCost =
|
let gasCost =
|
||||||
cpt.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
cpt.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
||||||
cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(SelfDestruct,
|
||||||
gasCost, reason = "SELFDESTRUCT EIP150")
|
gasCost, reason = "SELFDESTRUCT EIP150")
|
||||||
cpt.selfDestruct(beneficiary)
|
cpt.selfDestruct(beneficiary)
|
||||||
|
|
||||||
@ -117,7 +116,7 @@ const
|
|||||||
|
|
||||||
let gasCost =
|
let gasCost =
|
||||||
cpt.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
cpt.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
||||||
cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(SelfDestruct,
|
||||||
gasCost, reason = "SELFDESTRUCT EIP161")
|
gasCost, reason = "SELFDESTRUCT EIP161")
|
||||||
cpt.selfDestruct(beneficiary)
|
cpt.selfDestruct(beneficiary)
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ const
|
|||||||
db.accessList(beneficiary)
|
db.accessList(beneficiary)
|
||||||
gasCost = gasCost + ColdAccountAccessCost
|
gasCost = gasCost + ColdAccountAccessCost
|
||||||
|
|
||||||
cpt.gasMeter.consumeGas(
|
cpt.opcodeGastCost(SelfDestruct,
|
||||||
gasCost, reason = "SELFDESTRUCT EIP2929")
|
gasCost, reason = "SELFDESTRUCT EIP2929")
|
||||||
cpt.selfDestruct(beneficiary)
|
cpt.selfDestruct(beneficiary)
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ type
|
|||||||
paPairing = 0x08,
|
paPairing = 0x08,
|
||||||
# Istanbul
|
# Istanbul
|
||||||
paBlake2bf = 0x09,
|
paBlake2bf = 0x09,
|
||||||
|
paPointEvaluation = 0x0A
|
||||||
# Berlin
|
# Berlin
|
||||||
# EIP-2537: disabled
|
# EIP-2537: disabled
|
||||||
# reason: not included in berlin
|
# reason: not included in berlin
|
||||||
@ -47,7 +48,7 @@ type
|
|||||||
# paBlsMapG1
|
# paBlsMapG1
|
||||||
# paBlsMapG2
|
# paBlsMapG2
|
||||||
# Cancun
|
# Cancun
|
||||||
paPointEvaluation = 0x0A
|
|
||||||
|
|
||||||
proc getMaxPrecompileAddr(fork: EVMFork): PrecompileAddresses =
|
proc getMaxPrecompileAddr(fork: EVMFork): PrecompileAddresses =
|
||||||
if fork < FkByzantium: paIdentity
|
if fork < FkByzantium: paIdentity
|
||||||
@ -705,7 +706,7 @@ proc execPrecompiles*(computation: Computation, fork: EVMFork): bool {.inline.}
|
|||||||
of paPairing: bn256ecPairing(computation, fork)
|
of paPairing: bn256ecPairing(computation, fork)
|
||||||
of paBlake2bf: blake2bf(computation)
|
of paBlake2bf: blake2bf(computation)
|
||||||
of paPointEvaluation: pointEvaluation(computation)
|
of paPointEvaluation: pointEvaluation(computation)
|
||||||
else: discard
|
#else: discard
|
||||||
# EIP 2537: disabled
|
# EIP 2537: disabled
|
||||||
# reason: not included in berlin
|
# reason: not included in berlin
|
||||||
# of paBlsG1Add: blsG1Add(computation)
|
# of paBlsG1Add: blsG1Add(computation)
|
||||||
|
@ -17,7 +17,7 @@ import
|
|||||||
../db/accounts_cache,
|
../db/accounts_cache,
|
||||||
../common/[common, evmforks],
|
../common/[common, evmforks],
|
||||||
./async/data_sources,
|
./async/data_sources,
|
||||||
./interpreter/op_codes,
|
./interpreter/[op_codes, gas_costs],
|
||||||
./types
|
./types
|
||||||
|
|
||||||
proc init(
|
proc init(
|
||||||
@ -391,28 +391,32 @@ proc captureOpStart*(vmState: BaseVMState, comp: Computation, pc: int,
|
|||||||
op: Op, gas: GasInt,
|
op: Op, gas: GasInt,
|
||||||
depth: int): int =
|
depth: int): int =
|
||||||
if vmState.tracingEnabled:
|
if vmState.tracingEnabled:
|
||||||
result = vmState.tracer.captureOpStart(comp, pc, op, gas, depth)
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
||||||
|
result = vmState.tracer.captureOpStart(comp, fixed, pc, op, gas, depth)
|
||||||
|
|
||||||
proc callFamilyGas*(vmState: BaseVMState,
|
proc captureGasCost*(vmState: BaseVMState,
|
||||||
comp: Computation,
|
comp: Computation,
|
||||||
op: Op, gas: GasInt,
|
op: Op, gasCost: GasInt, gasRemaining: GasInt,
|
||||||
depth: int) =
|
depth: int) =
|
||||||
if vmState.tracingEnabled:
|
if vmState.tracingEnabled:
|
||||||
vmState.tracer.callFamilyGas(comp, op, gas, depth)
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
||||||
|
vmState.tracer.captureGasCost(comp, fixed, op, gasCost, gasRemaining, depth)
|
||||||
|
|
||||||
proc captureOpEnd*(vmState: BaseVMState, comp: Computation, pc: int,
|
proc captureOpEnd*(vmState: BaseVMState, comp: Computation, pc: int,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, opIndex: int) =
|
depth: int, opIndex: int) =
|
||||||
if vmState.tracingEnabled:
|
if vmState.tracingEnabled:
|
||||||
vmState.tracer.captureOpEnd(comp, pc, op, gas, refund, rData, depth, opIndex)
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
||||||
|
vmState.tracer.captureOpEnd(comp, fixed, pc, op, gas, refund, rData, depth, opIndex)
|
||||||
|
|
||||||
proc captureFault*(vmState: BaseVMState, comp: Computation, pc: int,
|
proc captureFault*(vmState: BaseVMState, comp: Computation, pc: int,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, error: Option[string]) =
|
depth: int, error: Option[string]) =
|
||||||
if vmState.tracingEnabled:
|
if vmState.tracingEnabled:
|
||||||
vmState.tracer.captureFault(comp, pc, op, gas, refund, rData, depth, error)
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
||||||
|
vmState.tracer.captureFault(comp, fixed, pc, op, gas, refund, rData, depth, error)
|
||||||
|
|
||||||
proc capturePrepare*(vmState: BaseVMState, comp: Computation, depth: int) =
|
proc capturePrepare*(vmState: BaseVMState, comp: Computation, depth: int) =
|
||||||
if vmState.tracingEnabled:
|
if vmState.tracingEnabled:
|
||||||
|
@ -28,17 +28,7 @@ type
|
|||||||
stack: JsonNode
|
stack: JsonNode
|
||||||
storageKeys: seq[HashSet[UInt256]]
|
storageKeys: seq[HashSet[UInt256]]
|
||||||
index: int
|
index: int
|
||||||
callFamilyNode: JsonNode
|
node: JsonNode
|
||||||
|
|
||||||
const
|
|
||||||
callFamily = [
|
|
||||||
Create,
|
|
||||||
Create2,
|
|
||||||
Call,
|
|
||||||
CallCode,
|
|
||||||
DelegateCall,
|
|
||||||
StaticCall,
|
|
||||||
]
|
|
||||||
|
|
||||||
template stripLeadingZeros(value: string): string =
|
template stripLeadingZeros(value: string): string =
|
||||||
var cidx = 0
|
var cidx = 0
|
||||||
@ -47,9 +37,12 @@ template stripLeadingZeros(value: string): string =
|
|||||||
cidx.inc
|
cidx.inc
|
||||||
value[cidx .. ^1]
|
value[cidx .. ^1]
|
||||||
|
|
||||||
proc encodeHexInt(x: SomeInteger): JsonNode =
|
proc encodeHex(x: SomeInteger): JsonNode =
|
||||||
%("0x" & x.toHex.stripLeadingZeros.toLowerAscii)
|
%("0x" & x.toHex.stripLeadingZeros.toLowerAscii)
|
||||||
|
|
||||||
|
proc encodeHex(x: UInt256): string =
|
||||||
|
"0x" & x.dumpHex.stripLeadingZeros
|
||||||
|
|
||||||
proc `%`(x: openArray[byte]): JsonNode =
|
proc `%`(x: openArray[byte]): JsonNode =
|
||||||
if x.len == 0:
|
if x.len == 0:
|
||||||
%("")
|
%("")
|
||||||
@ -77,16 +70,15 @@ iterator storage(ctx: JsonTracer, compDepth: int): UInt256 =
|
|||||||
|
|
||||||
proc captureOpImpl(ctx: JsonTracer, c: Computation, pc: int,
|
proc captureOpImpl(ctx: JsonTracer, c: Computation, pc: int,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte], depth: int, error: Option[string]) {.gcsafe.} =
|
||||||
depth: int, error: Option[string]) {.gcsafe.} =
|
|
||||||
let
|
let
|
||||||
gasCost = ctx.gas - gas
|
gasCost = ctx.gas - gas
|
||||||
|
|
||||||
var res = %{
|
var res = %{
|
||||||
"pc": %(ctx.pc),
|
"pc": %(ctx.pc),
|
||||||
"op": %(op.int),
|
"op": %(op.int),
|
||||||
"gas": encodeHexInt(ctx.gas),
|
"gas": encodeHex(ctx.gas),
|
||||||
"gasCost": encodeHexInt(gasCost),
|
"gasCost": encodeHex(gasCost),
|
||||||
"memSize": %(c.memory.len)
|
"memSize": %(c.memory.len)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +106,7 @@ proc captureOpImpl(ctx: JsonTracer, c: Computation, pc: int,
|
|||||||
var stateDB = c.vmState.stateDB
|
var stateDB = c.vmState.stateDB
|
||||||
for key in ctx.storage(c.msg.depth):
|
for key in ctx.storage(c.msg.depth):
|
||||||
let value = stateDB.getStorage(c.msg.contractAddress, key)
|
let value = stateDB.getStorage(c.msg.contractAddress, key)
|
||||||
storage["0x" & key.dumpHex.stripLeadingZeros] =
|
storage[key.encodeHex] = %(value.encodeHex)
|
||||||
%("0x" & value.dumpHex.stripLeadingZeros)
|
|
||||||
res["storage"] = storage
|
res["storage"] = storage
|
||||||
|
|
||||||
res["depth"] = %(depth)
|
res["depth"] = %(depth)
|
||||||
@ -125,10 +116,7 @@ proc captureOpImpl(ctx: JsonTracer, c: Computation, pc: int,
|
|||||||
if error.isSome:
|
if error.isSome:
|
||||||
res["error"] = %(error.get)
|
res["error"] = %(error.get)
|
||||||
|
|
||||||
if op in callFamily:
|
ctx.node = res
|
||||||
ctx.callFamilyNode = res
|
|
||||||
else:
|
|
||||||
ctx.writeJson(res)
|
|
||||||
|
|
||||||
proc newJsonTracer*(stream: Stream, flags: set[TracerFlags], pretty: bool): JsonTracer =
|
proc newJsonTracer*(stream: Stream, flags: set[TracerFlags], pretty: bool): JsonTracer =
|
||||||
JsonTracer(
|
JsonTracer(
|
||||||
@ -157,15 +145,15 @@ method captureEnd*(ctx: JsonTracer, comp: Computation, output: openArray[byte],
|
|||||||
gasUsed: GasInt, error: Option[string]) {.gcsafe.} =
|
gasUsed: GasInt, error: Option[string]) {.gcsafe.} =
|
||||||
var res = %{
|
var res = %{
|
||||||
"output": %(output),
|
"output": %(output),
|
||||||
"gasUsed": encodeHexInt(gasUsed)
|
"gasUsed": encodeHex(gasUsed)
|
||||||
}
|
}
|
||||||
if error.isSome:
|
if error.isSome:
|
||||||
res["error"] = %(error.get())
|
res["error"] = %(error.get())
|
||||||
ctx.writeJson(res)
|
ctx.writeJson(res)
|
||||||
|
|
||||||
# Opcode level
|
# Opcode level
|
||||||
method captureOpStart*(ctx: JsonTracer, c: Computation, pc: int,
|
method captureOpStart*(ctx: JsonTracer, c: Computation,
|
||||||
op: Op, gas: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt,
|
||||||
depth: int): int {.gcsafe.} =
|
depth: int): int {.gcsafe.} =
|
||||||
ctx.gas = gas
|
ctx.gas = gas
|
||||||
ctx.pc = pc
|
ctx.pc = pc
|
||||||
@ -173,7 +161,7 @@ method captureOpStart*(ctx: JsonTracer, c: Computation, pc: int,
|
|||||||
if TracerFlags.DisableStack notin ctx.flags:
|
if TracerFlags.DisableStack notin ctx.flags:
|
||||||
ctx.stack = newJArray()
|
ctx.stack = newJArray()
|
||||||
for v in c.stack.values:
|
for v in c.stack.values:
|
||||||
ctx.stack.add(%("0x" & v.dumpHex.stripLeadingZeros))
|
ctx.stack.add(%(v.encodeHex))
|
||||||
|
|
||||||
if TracerFlags.DisableStorage notin ctx.flags and op == SSTORE:
|
if TracerFlags.DisableStorage notin ctx.flags and op == SSTORE:
|
||||||
try:
|
try:
|
||||||
@ -184,47 +172,71 @@ method captureOpStart*(ctx: JsonTracer, c: Computation, pc: int,
|
|||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
error "JsonTracer captureOpStart", msg=ex.msg
|
error "JsonTracer captureOpStart", msg=ex.msg
|
||||||
|
|
||||||
if op in callFamily:
|
|
||||||
try:
|
try:
|
||||||
ctx.captureOpImpl(c, pc, op, 0, 0, [], depth, none(string))
|
ctx.captureOpImpl(c, pc, op, 0, 0, [], depth, none(string))
|
||||||
except RlpError as ex:
|
except RlpError as ex:
|
||||||
error "JsonTracer captureOpEnd", msg=ex.msg
|
error "JsonTracer captureOpStart", msg=ex.msg
|
||||||
|
|
||||||
# make sure captureOpEnd get the right opIndex
|
# make sure captureOpEnd get the right opIndex
|
||||||
result = ctx.index
|
result = ctx.index
|
||||||
inc ctx.index
|
inc ctx.index
|
||||||
|
|
||||||
method callFamilyGas*(ctx: JsonTracer, comp: Computation,
|
method captureGasCost*(ctx: JsonTracer, comp: Computation,
|
||||||
op: Op, gas: GasInt,
|
fixed: bool, op: Op, gasCost: GasInt, gasRemaining: GasInt,
|
||||||
depth: int) {.gcsafe.} =
|
depth: int) {.gcsafe.} =
|
||||||
doAssert(op in callFamily)
|
doAssert(ctx.node.isNil.not)
|
||||||
doAssert(ctx.callFamilyNode.isNil.not)
|
let res = ctx.node
|
||||||
let res = ctx.callFamilyNode
|
res["gasCost"] = encodeHex(gasCost)
|
||||||
res["gasCost"] = encodeHexInt(gas)
|
|
||||||
ctx.writeJson(res)
|
|
||||||
|
|
||||||
method captureOpEnd*(ctx: JsonTracer, comp: Computation, pc: int,
|
if gasCost <= gasRemaining and not fixed:
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
ctx.writeJson(res)
|
||||||
|
ctx.node = nil
|
||||||
|
# else:
|
||||||
|
# OOG will be handled by captureFault
|
||||||
|
# opcode with fixed gasCost will be handled by captureOpEnd
|
||||||
|
|
||||||
|
method captureOpEnd*(ctx: JsonTracer, comp: Computation,
|
||||||
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, opIndex: int) {.gcsafe.} =
|
depth: int, opIndex: int) {.gcsafe.} =
|
||||||
|
if fixed:
|
||||||
|
doAssert(ctx.node.isNil.not)
|
||||||
|
let res = ctx.node
|
||||||
|
res["refund"] = %(refund)
|
||||||
|
|
||||||
if op in callFamily:
|
if TracerFlags.DisableReturnData notin ctx.flags:
|
||||||
# call family opcode is processed in captureOpStart
|
res["returnData"] = %(rData)
|
||||||
|
|
||||||
|
ctx.writeJson(res)
|
||||||
|
ctx.node = nil
|
||||||
|
return
|
||||||
|
|
||||||
|
method captureFault*(ctx: JsonTracer, comp: Computation,
|
||||||
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
|
rData: openArray[byte],
|
||||||
|
depth: int, error: Option[string]) {.gcsafe.} =
|
||||||
|
|
||||||
|
if ctx.node.isNil.not:
|
||||||
|
let res = ctx.node
|
||||||
|
res["refund"] = %(refund)
|
||||||
|
|
||||||
|
if TracerFlags.DisableReturnData notin ctx.flags:
|
||||||
|
res["returnData"] = %(rData)
|
||||||
|
|
||||||
|
if error.isSome:
|
||||||
|
res["error"] = %(error.get)
|
||||||
|
|
||||||
|
ctx.writeJson(res)
|
||||||
|
ctx.node = nil
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
ctx.captureOpImpl(comp, pc, op, gas, refund, rData, depth, none(string))
|
|
||||||
except RlpError as ex:
|
|
||||||
error "JsonTracer captureOpEnd", msg=ex.msg
|
|
||||||
|
|
||||||
method captureFault*(ctx: JsonTracer, comp: Computation, pc: int,
|
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
|
||||||
rData: openArray[byte],
|
|
||||||
depth: int, error: Option[string]) {.gcsafe.} =
|
|
||||||
try:
|
try:
|
||||||
ctx.captureOpImpl(comp, pc, op, gas, refund, rData, depth, error)
|
ctx.captureOpImpl(comp, pc, op, gas, refund, rData, depth, error)
|
||||||
|
doAssert(ctx.node.isNil.not)
|
||||||
|
ctx.writeJson(ctx.node)
|
||||||
|
ctx.node = nil
|
||||||
except RlpError as ex:
|
except RlpError as ex:
|
||||||
error "JsonTracer captureOpEnd", msg=ex.msg
|
error "JsonTracer captureOpFault", msg=ex.msg
|
||||||
|
|
||||||
proc close*(ctx: JsonTracer) =
|
proc close*(ctx: JsonTracer) =
|
||||||
ctx.stream.close()
|
ctx.stream.close()
|
||||||
|
@ -71,8 +71,8 @@ method capturePrepare*(ctx: LegacyTracer, comp: Computation, depth: int) {.gcsaf
|
|||||||
ctx.storageKeys[depth] = initHashSet[UInt256]()
|
ctx.storageKeys[depth] = initHashSet[UInt256]()
|
||||||
|
|
||||||
# Opcode level
|
# Opcode level
|
||||||
method captureOpStart*(ctx: LegacyTracer, c: Computation, pc: int,
|
method captureOpStart*(ctx: LegacyTracer, c: Computation,
|
||||||
op: Op, gas: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt,
|
||||||
depth: int): int {.gcsafe.} =
|
depth: int): int {.gcsafe.} =
|
||||||
try:
|
try:
|
||||||
let
|
let
|
||||||
@ -126,8 +126,8 @@ method captureOpStart*(ctx: LegacyTracer, c: Computation, pc: int,
|
|||||||
except InsufficientStack as ex:
|
except InsufficientStack as ex:
|
||||||
error "LegacyTracer captureOpEnd", msg=ex.msg
|
error "LegacyTracer captureOpEnd", msg=ex.msg
|
||||||
|
|
||||||
method captureOpEnd*(ctx: LegacyTracer, c: Computation, pc: int,
|
method captureOpEnd*(ctx: LegacyTracer, c: Computation,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, opIndex: int) {.gcsafe.} =
|
depth: int, opIndex: int) {.gcsafe.} =
|
||||||
try:
|
try:
|
||||||
@ -156,8 +156,8 @@ method captureOpEnd*(ctx: LegacyTracer, c: Computation, pc: int,
|
|||||||
except RlpError as ex:
|
except RlpError as ex:
|
||||||
error "LegacyTracer captureOpEnd", msg=ex.msg
|
error "LegacyTracer captureOpEnd", msg=ex.msg
|
||||||
|
|
||||||
method captureFault*(ctx: LegacyTracer, comp: Computation, pc: int,
|
method captureFault*(ctx: LegacyTracer, comp: Computation,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, error: Option[string]) {.gcsafe.} =
|
depth: int, error: Option[string]) {.gcsafe.} =
|
||||||
try:
|
try:
|
||||||
|
@ -169,28 +169,28 @@ method captureExit*(ctx: TracerRef, comp: Computation, output: openArray[byte],
|
|||||||
discard
|
discard
|
||||||
|
|
||||||
# Opcode level
|
# Opcode level
|
||||||
method captureOpStart*(ctx: TracerRef, comp: Computation, pc: int,
|
method captureOpStart*(ctx: TracerRef, comp: Computation,
|
||||||
op: Op, gas: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt,
|
||||||
depth: int): int {.base, gcsafe.} =
|
depth: int): int {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method callFamilyGas*(ctx: TracerRef, comp: Computation,
|
method captureGasCost*(ctx: TracerRef, comp: Computation,
|
||||||
op: Op, gas: GasInt,
|
fixed: bool, op: Op, gasCost: GasInt,
|
||||||
depth: int) {.base, gcsafe.} =
|
gasRemaining: GasInt, depth: int) {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method captureOpEnd*(ctx: TracerRef, comp: Computation, pc: int,
|
method captureOpEnd*(ctx: TracerRef, comp: Computation,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, opIndex: int) {.base, gcsafe.} =
|
depth: int, opIndex: int) {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method captureFault*(ctx: TracerRef, comp: Computation, pc: int,
|
method captureFault*(ctx: TracerRef, comp: Computation,
|
||||||
op: Op, gas: GasInt, refund: GasInt,
|
fixed: bool, pc: int, op: Op, gas: GasInt, refund: GasInt,
|
||||||
rData: openArray[byte],
|
rData: openArray[byte],
|
||||||
depth: int, error: Option[string]) {.base, gcsafe.} =
|
depth: int, error: Option[string]) {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
# Called at the start of EVM interpreter loop
|
||||||
method capturePrepare*(ctx: TracerRef, comp: Computation, depth: int) {.base, gcsafe.} =
|
method capturePrepare*(ctx: TracerRef, comp: Computation, depth: int) {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
@ -43,7 +43,7 @@ export
|
|||||||
vms.captureEnter,
|
vms.captureEnter,
|
||||||
vms.captureExit,
|
vms.captureExit,
|
||||||
vms.captureOpStart,
|
vms.captureOpStart,
|
||||||
vms.callFamilyGas,
|
vms.captureGasCost,
|
||||||
vms.captureOpEnd,
|
vms.captureOpEnd,
|
||||||
vms.captureFault,
|
vms.captureFault,
|
||||||
vms.capturePrepare
|
vms.capturePrepare
|
||||||
|
@ -515,6 +515,15 @@ const
|
|||||||
output: T8nOutput(trace: true, result: true),
|
output: T8nOutput(trace: true, result: true),
|
||||||
expOut: "exp.txt",
|
expOut: "exp.txt",
|
||||||
),
|
),
|
||||||
|
TestSpec(
|
||||||
|
name : "EVM tracer CALL family exception",
|
||||||
|
base : "testdata/00-521",
|
||||||
|
input : t8nInput(
|
||||||
|
"alloc.json", "txs.json", "env.json", "Shanghai", "0",
|
||||||
|
),
|
||||||
|
output: T8nOutput(trace: true, result: true),
|
||||||
|
expOut: "exp.txt",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
|
68
tools/t8n/testdata/00-521/alloc.json
vendored
Normal file
68
tools/t8n/testdata/00-521/alloc.json
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"0x00000000000000000000000000000000000000f1": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x600060006000600060fa5af4507f60095450600354506000600055600654507f60faff61507a6c957f60075450606000527fa06000536083600153600060025360f360036000527f536032600453600560606020527e527f055360606006536002600753606060085360006020527f6009536055606040527f0a536060600b536020527f6001600c536054600d536050600e536040527f60606060527f600f5360206010536060601153600060405260606060536012606153605360606080527f527f606253606060635360f3606453606060655360136066536053606753606060a0527f60686080527f5360146069536060606a536000606b5360f3606c536000606d6060c0527e6000f5600060a0527f6000600060006000855af15050823d76b158605c326060e0527e60006000600060006060c0527f095af250337583987e9360f4ff6000600060610100527e6000600060055af2509843046560e0527f468456603e5f3084576004545060610120527e600060006000600060f75af25091636563610100527f936a83180260006000610140527f60006000600060f85af2507e6001545060035450600060610120526000610140610160527f5360606101415360006101425360606101435360006101445360606101455360610180527f0561014653605a6101475360f461014853605061014953606061014a536000616101a0527f014b53606061014c53600461014d53605561014e53608d61014f53607d6101506101c0527f53605961015153607d61015253600961015353608f61015453606061015553606101e0527f0261015653606061015753600161015853605561015953606061015a5360206161020052600161022053605b61022153605361022253606061022353606061022453606161022553600161022653605c61022753605361022853606061022953600061022a53606161022b53600161022c53605d61022d53605361022e53606061022f5360fd61023053606161023153600161023253605e61023353605361023453606161023553600161023653605f6102375360606102385360006102395360f361023a53600061023b60006000f560006000600060006000855af25050",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f2": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x60045450600060006000600060f55af450600060025560f9ff068c6a914360016003551cfe5a8a5e68fe50201d4265600bff60206000fd",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f3": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x6001600255cf7f60005450600954506007545060065450600354507f6000600060006000600a5a6000527ff450600eff7f6000600355600354506002545060086000527f54507f7f6006546020527f507ff988b145087f887a6000527f34393a977050649aa3f47f6020527f6002606040527f015560066000527f546000527f50600554506020527f6000527f6004546040526060527f7f5060016003556001600255600060046020527f556000527f606040527f20526080527f7f6060527f6001600155600754506020527f600160045560026002556040527f60a0527f60016060526080527f7f600055600060006040527f556007546020527f50600360c0527f54506040527f60606060a0527f606080527f527f60005360026001536054600260e0527f536060527f605060035360506060c0527f045360616060a0527f40526080527f610100527f7f606060527f05536041600653605b600760e0527f6080527f53609f600860c0610120527f527f5360d760095360a0527f6060600a536000600b610100527f606080527f60610140527f527f536060606060e0527fa0527f0c536004600d5360c0527f60610120527f55610160527f600e536060600f536020601053606060610100527f60a0527f11536060c05261610180527f0140527f7f60805260e0527f600060a053606060a153601260a2610120527f536101a0527f605360a3610160527f53606060a4536060c05260e052610100527f7f7ffd60a56101c0527f53606060610140527f610180527fa653601360a753605360a853606060a953606101e0527f1460aa5360610120527f606101006101a0527f610160527f527f6060e0527fab610200527f53600060ac5360f360ad53600060ae600060006101c0527ff561014052610180610220527f527f7f600060006000610120527f6000600085610100527f6101e0527f5af150610240527f50507f918b6b6a6101a0527fa1610160527fa1760652600aff50103f45610200610260527f527f610140527ff1845e601917087f45796101c0527f61012052600b61018052610280527f7f61610220527f014053603761014153601461014253610160527f6101e0527f6102a0527f60136101435360610240527f5a6101446101a0527f53606061014553602061016102c0527f4653606061610200527f0147610260527f5360006101805260616101a05360616102e0527f01c0527f016101a15360486101a2536102610280527f20527f60536101a35360610300527f606101a45360f36101a5536061616101e0527f01a6536102a0527f6001616102610320527f40527f01a75360496101a85360536101a95360616101aa536001616102c0527f610340527f01ab610200527f53610260527f604a6101ac5360606101ad5360006101ae5360610360527f6102e0527ff36101af5360006101b0600061610280527f022052606061024053610380527f6000610241610300527f5360f56102425360606102435360006102446102a0526103a0527f7f536060610245536000610320527f61024653606061024753600061024853606103c0527f6061024953606102c0527e61024a53610340527f606061024b53600061024c536103e0527f608561024d53605a61024e5360f2616102e05260610360527f0261030053604f610400527f61030153605361030253606061030353605061030453606161610380527f0305610420527f53600261030653605061030753605361030853606061030953605061030a6103610440527fa0527f53606161030b53600261030c53605161030d53605361030e5360616103610460527f0f53606103c0527f026103105360526103115360606103125360006103135360610480527ff3610314536103156103e05260606104005360006104015360606104025360006104a0527f6104035360f061040453606061040553600061040653606061040753600061046104c0527f0853606061040953600061040a53606061040b53600061040c53606061040d536104e0527f600061040e53608561040f53605a6104105360f26104115360506104125360506105005260616105205360046105215360136105225360536105235360616105245360046105255360146105265360606105275360006105285360f36105295361052a60006000f06000600060006000845af45050",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f4": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x7f600260045560005450600054506052600053605960015360b0600253604860036000527f53606060045360006005536060600653600060075360606008536000600953606020527f60600a536000600b536060600c536000600d536060600e5360f7600f53605a606040527f105360f260115360506012536060601353602060145360606015536000601653606052606060805360f3608153606060825360176083536053608453606060855360186086536060608753600060885360f3608953608a60006000f060006000600060006000855af15050600060006000600060085af4509e6c9d1d971b000660f7ff600454506000600060006000600060025af2509c475968419b3aa08593a2600160015573723c5c93313020435e90136c69a060006000600060006000600b5af25082a34587374694600254502818e1600354506002ff60f6ff60025450600060006000600060085af45060006002555938175a79c36006ff60206000f3",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f5": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0xf570b11897ff9b1da093177f645c31168c93a46000600455cd600060045560206000f3",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f6": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x60206000fd",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f7": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x7f6002545060006000556002600355600654506000600155600854507f60faff9b6000527f023f5bfa904270645484563c3af0748b956c546afdfa825b888a60066000527f6020527fff236000600060006000600060f25af2506000600060006000600060f95af2506040527f6020527f60025450676003545060006000600060006000600a5af1509c0238456060527fa1375d086040527f6a0173ff687402743080530196697c6000600060006000606080527ff75af450507965fe6060527f0360006000600060006000600d5af2507f60006060a0527e55600060025560035450606080527e6004556060600053602060015360606060c0527f60005260026020536053602153606060a0527f6022536000602353606060245360e0527f60036025536053602653606060275360f3602860c0527f536060602953600460610100527f2a536053602b536060602c536005602d536060602e536060e0527e602f5360f3610120527f6030536000603160006000f56000600060006000845af450501561010052609f610140527f6101205360876101215360646101225360536101235360606101245360006101610160527f2553606061012653600061012753606061012853600061012953606061012a53610180527f600061012b53606061012c53600061012d53606061012e5360f761012f53605a6101a0527f6101305360f161013153605061013253606061013353602061013453606061016101c05260356101e05360536101e15360606101e25360006101e35360616101e45360016101e55360366101e65360536101e75360606101e85360f36101e95360616101ea5360016101eb5360376101ec5360536101ed5360616101ee5360016101ef5360386101f05360606101f15360006101f25360f36101f3536101f460006000f06000600060006000845af45050",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f8": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x600060006000600060065af4506000600060006000600060f65af1507f600054507f663a148bfd0ba3396000600060006000600060f25af250600060006000527f60006000606000527e600c5af250600454507f7f9c757985621d9779001466466020527f78183760006002556020527faf60006003550047149a046000527ff06000527f6040527f080864543efe3f3f445803356040527f600354505a8e45a4b071383862fa19606060527f20527f9c5b7c52076020527f600160036060527f55b27f6007545060006004556080527f600260025560016040527f6002556007545060026080527f6040527f5450600160a0527f6002556000527f60065450600160016060527f556000545060a0527f6008545060c0527f600654506060527f60016004556007545060046020527f6080527f5460c0527f60e0527f506060600053600060015360606002536080527f600060035360606004536060610100527f60e0527fa0527e6005536040527f6060600653600060075360606060a0527f08610120527f53600060610100527f095360c0527f6060600a536006600b53605a6060527f60610140527f0c5360f2600d536060610120527fc0527f50600e60e0527f536060600f536020610160527f6010536060601153600060126080610140527f52605360a0536060e052610100610180527f527f7f6060a15360f360a253606060a3536013610160527f60a453605360a5536101a0527f606060a6536014610120527f60610100527fa753606060a8610180527f5360006101c0527f60a95360f360aa53600060ab60006000f5610140527f600060006000616101a06101e0527f527f0120527f6000845af450509e20915e89f0684660026000559a610160527f610200527f60006101c0527f600060006000600060610140527f0d5af15060016002556009610220527fff3f8c329761016101e0527f80527f7f60006002556000545060095450600161610240527f0160527f6003556000600055610200527f6000606101a0527f02556000545060610260527e527f600260035560026003557f610180610220527f527f6000600060006101610280527fc0527f6000600060035af25060005450600d60205260610240527fff604053606102a0527f60606101a0527f416101e0527f5360016042536060604353600260610260527f6102c0527f445360556045536060604653602060475361610200527f01c0527f60606048536102e0527f610280527f600060495360f3604a536060604b536000604c5360526061022052610300527f7f4d5360606102a0527f6101e0527f604e536020604f53606060505360006051610320527f5360f3605253610240526102c0527f7f605360006000f0600061020052606061610340527f0220536000610221536060610222536102e0527f60610260527e610223536060610360527f6102245360006102255360606102265360006102610300527f27536085616102610380527f80527f022853605a6102295360f161022a53605061022b5360610320527f50616103a0527f022c5361022d60006102a05260f36102c0536102c160006000f06000600061036103c0527f40526060610360536000610361536060610362536000610363536084610364536103e052606061040053605a6104015360616104025360036104035360656104045360536104055360606104065360f461040753606161040853600361040953606661040a53605361040b53606061040c53605061040d53606161040e53600361040f53606761041053605361041153606061041253605061041353606161041453600361041553606861041653605361041753606161041853600361041953606961041a53606061041b53600061041c5360f361041d5361041e60006000f060006000600060006000855af15050",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000f9": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x9f9d404467600060006000600060f65af450533a9e7060006000600060006000600e5af150f5032095fd177d99306000600060006000600060005af1506000600060006000600d5af450916858b03c60006000600060006000600e5af25060206000f3",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x00000000000000000000000000000000000000fa": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x6000600060006000600060fa5af15060206000fd",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||||
|
"balance": "0xffffffffff",
|
||||||
|
"code": "0x",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"storage": {}
|
||||||
|
}
|
||||||
|
}
|
10
tools/t8n/testdata/00-521/env.json
vendored
Normal file
10
tools/t8n/testdata/00-521/env.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"currentBaseFee": "0x10",
|
||||||
|
"currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||||
|
"currentDifficulty": "0x0",
|
||||||
|
"currentGasLimit": "0x26e1f476fe1e22",
|
||||||
|
"currentNumber": "0x1",
|
||||||
|
"currentRandom": "0x0000000000000000000000000000000000000000000000000000000000020000",
|
||||||
|
"currentTimestamp": "0x3e8",
|
||||||
|
"withdrawals": [],
|
||||||
|
}
|
17
tools/t8n/testdata/00-521/exp.txt
vendored
Normal file
17
tools/t8n/testdata/00-521/exp.txt
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{"pc":0,"op":96,"gas":"0xa54","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":2,"op":96,"gas":"0xa51","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":4,"op":96,"gas":"0xa4e","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":6,"op":96,"gas":"0xa4b","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":8,"op":96,"gas":"0xa48","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":10,"op":90,"gas":"0xa45","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xfa"],"depth":1,"refund":0,"opName":"GAS"}
|
||||||
|
{"pc":11,"op":244,"gas":"0xa43","gasCost":"0xa43","memSize":0,"stack":["0x0","0x0","0x0","0x0","0xfa","0xa43"],"depth":1,"refund":0,"opName":"DELEGATECALL"}
|
||||||
|
{"pc":0,"op":96,"gas":"0x1b","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":2,"op":96,"gas":"0x18","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":4,"op":96,"gas":"0x15","gasCost":"0x3","memSize":0,"stack":["0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":6,"op":96,"gas":"0x12","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":8,"op":96,"gas":"0xf","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":10,"op":96,"gas":"0xc","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":12,"op":90,"gas":"0x9","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xfa"],"depth":2,"refund":0,"opName":"GAS"}
|
||||||
|
{"pc":13,"op":241,"gas":"0x7","gasCost":"0x9","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xfa","0x7"],"depth":2,"refund":0,"opName":"CALL","error":"Opcode Dispatch Error: Out of gas: Needed 9 - Remaining 7 - Reason: Call, depth=2"}
|
||||||
|
{"pc":12,"op":80,"gas":"0x0","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"POP","error":"Opcode Dispatch Error: Out of gas: Needed 2 - Remaining 0 - Reason: Pop, depth=1"}
|
||||||
|
{"output":"","gasUsed":"0xa54","error":"Opcode Dispatch Error: Out of gas: Needed 2 - Remaining 0 - Reason: Pop, depth=1"}
|
14
tools/t8n/testdata/00-521/txs.json
vendored
Normal file
14
tools/t8n/testdata/00-521/txs.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "0x0",
|
||||||
|
"chainId": "0x1",
|
||||||
|
"input": "0x4235beb96136f67f5076ae8700b86ef876b2b95037c04c311ea03790a15b97389485f03361",
|
||||||
|
"gas": "0x5ea0",
|
||||||
|
"gasPrice": "0x10",
|
||||||
|
"nonce": "0x0",
|
||||||
|
"secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||||
|
"sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||||
|
"to": "0x00000000000000000000000000000000000000f1",
|
||||||
|
"value": "0x1a5474"
|
||||||
|
}
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user