core/vm: add ReturnStack etc to ScopeContext
This commit is contained in:
parent
d23c5e5e62
commit
2297ef65dd
|
@ -226,7 +226,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
// The depth-check is already done, and precompiles handled above
|
// The depth-check is already done, and precompiles handled above
|
||||||
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
||||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
||||||
ret, err = evm.interpreter.Run(contract, input, false)
|
ret, err = evm.interpreter.Run(contract, input, false, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||||
}
|
}
|
||||||
code := evm.StateDB.GetCode(addrCopy)
|
code := evm.StateDB.GetCode(addrCopy)
|
||||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
||||||
ret, err = evm.interpreter.Run(contract, input, false)
|
ret, err = evm.interpreter.Run(contract, input, false, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -341,7 +341,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||||
}
|
}
|
||||||
code := evm.StateDB.GetCode(addrCopy)
|
code := evm.StateDB.GetCode(addrCopy)
|
||||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code))
|
||||||
ret, err = evm.interpreter.Run(contract, input, false)
|
ret, err = evm.interpreter.Run(contract, input, false, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -403,7 +403,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
||||||
// When an error was returned by the EVM or when setting the creation code
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
// when we're in Homestead this also counts for code storage gas errors.
|
// when we're in Homestead this also counts for code storage gas errors.
|
||||||
ret, err = evm.interpreter.Run(contract, input, true)
|
ret, err = evm.interpreter.Run(contract, input, true, false)
|
||||||
gas = contract.Gas
|
gas = contract.Gas
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -533,7 +533,14 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
// initNewContract runs a new contract's creation code, performs checks on the
|
// initNewContract runs a new contract's creation code, performs checks on the
|
||||||
// resulting code that is to be deployed, and consumes necessary gas.
|
// resulting code that is to be deployed, and consumes necessary gas.
|
||||||
func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) {
|
func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) {
|
||||||
ret, err := evm.interpreter.Run(contract, nil, false)
|
// Charge the contract creation init gas in verkle mode
|
||||||
|
if evm.chainRules.IsEIP4762 {
|
||||||
|
if !contract.UseGas(evm.AccessEvents.ContractCreateInitGas(address, value.Sign() != 0), evm.Config.Tracer, tracing.GasChangeWitnessContractInit) {
|
||||||
|
return nil, ErrOutOfGas
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := evm.interpreter.Run(contract, nil, false, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
|
||||||
expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected))
|
expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected))
|
||||||
stack.push(x)
|
stack.push(x)
|
||||||
stack.push(y)
|
stack.push(y)
|
||||||
opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
|
opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil, 0, nil, false})
|
||||||
if len(stack.data) != 1 {
|
if len(stack.data) != 1 {
|
||||||
t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data))
|
t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data))
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ func TestAddMod(t *testing.T) {
|
||||||
stack.push(z)
|
stack.push(z)
|
||||||
stack.push(y)
|
stack.push(y)
|
||||||
stack.push(x)
|
stack.push(x)
|
||||||
opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
|
opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil, 0, nil, false})
|
||||||
actual := stack.pop()
|
actual := stack.pop()
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual)
|
t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual)
|
||||||
|
@ -258,7 +258,7 @@ func TestWriteExpectedValues(t *testing.T) {
|
||||||
y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y))
|
y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y))
|
||||||
stack.push(x)
|
stack.push(x)
|
||||||
stack.push(y)
|
stack.push(y)
|
||||||
opFn(&pc, interpreter, &ScopeContext{nil, stack, nil})
|
opFn(&pc, interpreter, &ScopeContext{nil, stack, nil, 0, nil, false})
|
||||||
actual := stack.pop()
|
actual := stack.pop()
|
||||||
result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
|
result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
|
||||||
var (
|
var (
|
||||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
scope = &ScopeContext{nil, stack, nil}
|
scope = &ScopeContext{nil, stack, nil, 0, nil, false}
|
||||||
evmInterpreter = NewEVMInterpreter(env)
|
evmInterpreter = NewEVMInterpreter(env)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -545,13 +545,13 @@ func TestOpMstore(t *testing.T) {
|
||||||
v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
|
v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
|
||||||
stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v)))
|
stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v)))
|
||||||
stack.push(new(uint256.Int))
|
stack.push(new(uint256.Int))
|
||||||
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
|
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil, 0, nil, false})
|
||||||
if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
|
if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
|
||||||
t.Fatalf("Mstore fail, got %v, expected %v", got, v)
|
t.Fatalf("Mstore fail, got %v, expected %v", got, v)
|
||||||
}
|
}
|
||||||
stack.push(new(uint256.Int).SetUint64(0x1))
|
stack.push(new(uint256.Int).SetUint64(0x1))
|
||||||
stack.push(new(uint256.Int))
|
stack.push(new(uint256.Int))
|
||||||
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
|
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil, 0, nil, false})
|
||||||
if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
|
if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
|
||||||
t.Fatalf("Mstore failed to overwrite previous value")
|
t.Fatalf("Mstore failed to overwrite previous value")
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||||
for i := 0; i < bench.N; i++ {
|
for i := 0; i < bench.N; i++ {
|
||||||
stack.push(value)
|
stack.push(value)
|
||||||
stack.push(memStart)
|
stack.push(memStart)
|
||||||
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
|
opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil, 0, nil, false})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ func TestOpTstore(t *testing.T) {
|
||||||
to = common.Address{1}
|
to = common.Address{1}
|
||||||
contractRef = contractRef{caller}
|
contractRef = contractRef{caller}
|
||||||
contract = NewContract(contractRef, AccountRef(to), new(uint256.Int), 0)
|
contract = NewContract(contractRef, AccountRef(to), new(uint256.Int), 0)
|
||||||
scopeContext = ScopeContext{mem, stack, contract}
|
scopeContext = ScopeContext{mem, stack, contract, 0, nil, false}
|
||||||
value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700")
|
value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ func BenchmarkOpKeccak256(bench *testing.B) {
|
||||||
for i := 0; i < bench.N; i++ {
|
for i := 0; i < bench.N; i++ {
|
||||||
stack.push(uint256.NewInt(32))
|
stack.push(uint256.NewInt(32))
|
||||||
stack.push(start)
|
stack.push(start)
|
||||||
opKeccak256(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
|
opKeccak256(&pc, evmInterpreter, &ScopeContext{mem, stack, nil, 0, nil, false})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,7 +705,7 @@ func TestCreate2Addresses(t *testing.T) {
|
||||||
stack.push(big.NewInt(int64(len(code)))) //size
|
stack.push(big.NewInt(int64(len(code)))) //size
|
||||||
stack.push(big.NewInt(0)) // memstart
|
stack.push(big.NewInt(0)) // memstart
|
||||||
stack.push(big.NewInt(0)) // value
|
stack.push(big.NewInt(0)) // value
|
||||||
gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0)
|
gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0, nil, false, 0)
|
||||||
fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String())
|
fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String())
|
||||||
*/
|
*/
|
||||||
expected := common.BytesToAddress(common.FromHex(tt.expected))
|
expected := common.BytesToAddress(common.FromHex(tt.expected))
|
||||||
|
@ -733,7 +733,7 @@ func TestRandom(t *testing.T) {
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
evmInterpreter = env.interpreter
|
evmInterpreter = env.interpreter
|
||||||
)
|
)
|
||||||
opRandom(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
|
opRandom(&pc, evmInterpreter, &ScopeContext{nil, stack, nil, 0, nil, false})
|
||||||
if len(stack.data) != 1 {
|
if len(stack.data) != 1 {
|
||||||
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
|
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
|
||||||
}
|
}
|
||||||
|
@ -775,7 +775,7 @@ func TestBlobHash(t *testing.T) {
|
||||||
evmInterpreter = env.interpreter
|
evmInterpreter = env.interpreter
|
||||||
)
|
)
|
||||||
stack.push(uint256.NewInt(tt.idx))
|
stack.push(uint256.NewInt(tt.idx))
|
||||||
opBlobHash(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
|
opBlobHash(&pc, evmInterpreter, &ScopeContext{nil, stack, nil, 0, nil, false})
|
||||||
if len(stack.data) != 1 {
|
if len(stack.data) != 1 {
|
||||||
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
|
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
|
||||||
}
|
}
|
||||||
|
@ -916,7 +916,7 @@ func TestOpMCopy(t *testing.T) {
|
||||||
mem.Resize(memorySize)
|
mem.Resize(memorySize)
|
||||||
}
|
}
|
||||||
// Do the copy
|
// Do the copy
|
||||||
opMcopy(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
|
opMcopy(&pc, evmInterpreter, &ScopeContext{mem, stack, nil, 0, nil, false})
|
||||||
want := common.FromHex(strings.ReplaceAll(tc.want, " ", ""))
|
want := common.FromHex(strings.ReplaceAll(tc.want, " ", ""))
|
||||||
if have := mem.store; !bytes.Equal(want, have) {
|
if have := mem.store; !bytes.Equal(want, have) {
|
||||||
t.Errorf("case %d: \nwant: %#x\nhave: %#x\n", i, want, have)
|
t.Errorf("case %d: \nwant: %#x\nhave: %#x\n", i, want, have)
|
||||||
|
|
|
@ -43,6 +43,10 @@ type ScopeContext struct {
|
||||||
Memory *Memory
|
Memory *Memory
|
||||||
Stack *Stack
|
Stack *Stack
|
||||||
Contract *Contract
|
Contract *Contract
|
||||||
|
|
||||||
|
CodeSection uint64
|
||||||
|
ReturnStack ReturnStack
|
||||||
|
InitCodeMode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemoryData returns the underlying memory slice. Callers must not modify the contents
|
// MemoryData returns the underlying memory slice. Callers must not modify the contents
|
||||||
|
@ -89,10 +93,33 @@ func (ctx *ScopeContext) ContractCode() []byte {
|
||||||
return ctx.Contract.Code
|
return ctx.Contract.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReturnStack []*ReturnContext
|
||||||
|
|
||||||
|
// Pop removes an element from the return stack
|
||||||
|
// Panics if the return stack is empty, which should
|
||||||
|
// never happen, since EOF code is verified for that.
|
||||||
|
func (ctx *ReturnStack) Pop() *ReturnContext {
|
||||||
|
item := (*ctx)[ctx.Len()-1]
|
||||||
|
*ctx = (*ctx)[:ctx.Len()-1]
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of the return stack
|
||||||
|
func (ctx *ReturnStack) Len() int {
|
||||||
|
return len(*ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReturnContext struct {
|
||||||
|
Section uint64
|
||||||
|
Pc uint64
|
||||||
|
StackHeight int
|
||||||
|
}
|
||||||
|
|
||||||
// EVMInterpreter represents an EVM interpreter
|
// EVMInterpreter represents an EVM interpreter
|
||||||
type EVMInterpreter struct {
|
type EVMInterpreter struct {
|
||||||
evm *EVM
|
evm *EVM
|
||||||
table *JumpTable
|
table *JumpTable
|
||||||
|
tableEOF *JumpTable
|
||||||
|
|
||||||
hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
|
hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
|
||||||
hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes
|
hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes
|
||||||
|
@ -148,7 +175,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evm.Config.ExtraEips = extraEips
|
evm.Config.ExtraEips = extraEips
|
||||||
return &EVMInterpreter{evm: evm, table: table}
|
return &EVMInterpreter{evm: evm, table: table, tableEOF: &pragueEOFInstructionSet}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run loops and evaluates the contract's code with the given input data and returns
|
// Run loops and evaluates the contract's code with the given input data and returns
|
||||||
|
@ -157,7 +184,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
|
||||||
// It's important to note that any errors returned by the interpreter should be
|
// It's important to note that any errors returned by the interpreter should be
|
||||||
// considered a revert-and-consume-all-gas operation except for
|
// considered a revert-and-consume-all-gas operation except for
|
||||||
// ErrExecutionReverted which means revert-and-keep-gas-left.
|
// ErrExecutionReverted which means revert-and-keep-gas-left.
|
||||||
func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) {
|
func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool, isInitCode bool) (ret []byte, err error) {
|
||||||
// Increment the call depth which is restricted to 1024
|
// Increment the call depth which is restricted to 1024
|
||||||
in.evm.depth++
|
in.evm.depth++
|
||||||
defer func() { in.evm.depth-- }()
|
defer func() { in.evm.depth-- }()
|
||||||
|
@ -179,13 +206,17 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
jt *JumpTable // current jump table
|
||||||
op OpCode // current opcode
|
op OpCode // current opcode
|
||||||
mem = NewMemory() // bound memory
|
mem = NewMemory() // bound memory
|
||||||
stack = newstack() // local stack
|
stack = newstack() // local stack
|
||||||
callContext = &ScopeContext{
|
callContext = &ScopeContext{
|
||||||
Memory: mem,
|
Memory: mem,
|
||||||
Stack: stack,
|
Stack: stack,
|
||||||
Contract: contract,
|
Contract: contract,
|
||||||
|
CodeSection: 0,
|
||||||
|
ReturnStack: []*ReturnContext{{Section: 0, Pc: 0, StackHeight: 0}},
|
||||||
|
InitCodeMode: isInitCode,
|
||||||
}
|
}
|
||||||
// For optimisation reason we're using uint64 as the program counter.
|
// For optimisation reason we're using uint64 as the program counter.
|
||||||
// It's theoretically possible to go above 2^64. The YP defines the PC
|
// It's theoretically possible to go above 2^64. The YP defines the PC
|
||||||
|
@ -208,6 +239,12 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||||
}()
|
}()
|
||||||
contract.Input = input
|
contract.Input = input
|
||||||
|
|
||||||
|
if contract.IsEOF() {
|
||||||
|
jt = in.tableEOF
|
||||||
|
} else {
|
||||||
|
jt = in.table
|
||||||
|
}
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
defer func() { // this deferred method handles exit-with-error
|
defer func() { // this deferred method handles exit-with-error
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -240,8 +277,8 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||||
|
|
||||||
// Get the operation from the jump table and validate the stack to ensure there are
|
// Get the operation from the jump table and validate the stack to ensure there are
|
||||||
// enough stack items available to perform the operation.
|
// enough stack items available to perform the operation.
|
||||||
op = contract.GetOp(pc)
|
op = contract.GetOp(pc, callContext.CodeSection)
|
||||||
operation := in.table[op]
|
operation := jt[op]
|
||||||
cost = operation.constantGas // For tracing
|
cost = operation.constantGas // For tracing
|
||||||
// Validate stack
|
// Validate stack
|
||||||
if sLen := stack.len(); sLen < operation.minStack {
|
if sLen := stack.len(); sLen < operation.minStack {
|
||||||
|
|
|
@ -77,7 +77,7 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
|
||||||
|
|
||||||
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit}), contract.Caller())
|
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit}), contract.Caller())
|
||||||
tracer.OnEnter(0, byte(vm.CALL), contract.Caller(), contract.Address(), []byte{}, startGas, value.ToBig())
|
tracer.OnEnter(0, byte(vm.CALL), contract.Caller(), contract.Address(), []byte{}, startGas, value.ToBig())
|
||||||
ret, err := env.Interpreter().Run(contract, []byte{}, false)
|
ret, err := env.Interpreter().Run(contract, []byte{}, false, false)
|
||||||
tracer.OnExit(0, ret, startGas-contract.Gas, err, true)
|
tracer.OnExit(0, ret, startGas-contract.Gas, err, true)
|
||||||
// Rest gas assumes no refund
|
// Rest gas assumes no refund
|
||||||
tracer.OnTxEnd(&types.Receipt{GasUsed: gasLimit - contract.Gas}, nil)
|
tracer.OnTxEnd(&types.Receipt{GasUsed: gasLimit - contract.Gas}, nil)
|
||||||
|
|
|
@ -62,7 +62,7 @@ func TestStoreCapture(t *testing.T) {
|
||||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
|
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
|
||||||
var index common.Hash
|
var index common.Hash
|
||||||
logger.OnTxStart(env.GetVMContext(), nil, common.Address{})
|
logger.OnTxStart(env.GetVMContext(), nil, common.Address{})
|
||||||
_, err := env.Interpreter().Run(contract, []byte{}, false)
|
_, err := env.Interpreter().Run(contract, []byte{}, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue