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